<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<link href="common/css/sf.css" rel="stylesheet" type="text/css"/>
<title>LibTactics: A Collection of Handy General-Purpose Tactics</title>
</head>
<link href="common/jquery-ui/jquery-ui.css" rel="stylesheet">
<script src="common/jquery-ui/external/jquery/jquery.js"></script>
<script src="common/jquery-ui/jquery-ui.js"></script>
<script src="common/toggleproofs.js"></script>
<link href="common/css/plf.css" rel="stylesheet" type="text/css"/>

<body>

<div id="page">

<div id="header">
<a href='https://coq-zh.github.io/SF-zh/index.html'>
<img src='common/media/image/sf_logo_sm.png'></a>
</br><a href='index.html'>  <span class='booktitleinheader'>Volume 2: 编程语言基础</span><br></br>
<ul id='menu'>
   <a href='toc.html'><li class='section_name'>目录</li></a>
   <a href='coqindex.html'><li class='section_name'>索引</li></a>
   <a href='deps.html'><li class='section_name'>路线</li></a>
</ul>
</a></div>

<div id="main">

<h1 class="libtitle">LibTactics<span class="subtitle">A Collection of Handy General-Purpose Tactics</span></h1>


<div class="code code-tight">

<span class="comment">(*&nbsp;Chapter&nbsp;maintained&nbsp;by&nbsp;Arthur&nbsp;Chargueraud&nbsp;*)</span><br/>
</div>

<div class="doc">
This file contains a set of tactics that extends the set of builtin
    tactics provided with the standard distribution of Coq. It intends
    to overcome a number of limitations of the standard set of tactics,
    and thereby to help user to write shorter and more robust scripts.

<div class="paragraph"> </div>

    Hopefully, Coq tactics will be improved as time goes by, and this
    file should ultimately be useless. In the meanwhile, serious Coq
    users will probably find it very useful.

<div class="paragraph"> </div>

    The present file contains the implementation and the detailed
    documentation of those tactics. The SF reader need not read this
    file; instead, he/she is encouraged to read the chapter named
    UseTactics.v, which is gentle introduction to the most useful
    tactics from the LibTactic library. 
<div class="paragraph"> </div>

 The main features offered are:

<div class="paragraph"> </div>

<ul class="doclist">
<li> More convenient syntax for naming hypotheses, with tactics for
         introduction and inversion that take as input only the name of
         hypotheses of type <span class="inlinecode"><span class="id" type="keyword">Prop</span></span>, rather than the name of all variables.

</li>
<li> Tactics providing true support for manipulating N-ary conjunctions,
         disjunctions and existentials, hidding the fact that the underlying
         implementation is based on binary propositions.

</li>
<li> Convenient support for automation: tactics followed with the symbol
         "~" or "*" will call automation on the generated subgoals.
         The symbol "~" stands for <span class="inlinecode"><span class="id" type="tactic">auto</span></span> and "*" for <span class="inlinecode"><span class="id" type="tactic">intuition</span></span> <span class="inlinecode"><span class="id" type="tactic">eauto</span></span>.
         These bindings can be customized.

</li>
<li> Forward-chaining tactics are provided to instantiate lemmas
         either with variable or hypotheses or a mix of both.

</li>
<li> A more powerful implementation of <span class="inlinecode"><span class="id" type="tactic">apply</span></span> is provided (it is based
         on <span class="inlinecode"><span class="id" type="tactic">refine</span></span> and thus behaves better with respect to conversion).

</li>
<li> An improved inversion tactic which substitutes equalities on variables
         generated by the standard inversion mecanism. Moreover, it supports
         the elimination of dependently-typed equalities (requires axiom <span class="inlinecode"><span class="id" type="var">K</span></span>,
         which is a weak form of Proof Irrelevance).

</li>
<li> Tactics for saving time when writing proofs, with tactics to
         asserts hypotheses or sub-goals, and improved tactics for
         clearing, renaming, and sorting hypotheses. 
</li>
</ul>

<div class="paragraph"> </div>

 External credits:

<div class="paragraph"> </div>

<ul class="doclist">
<li> thanks to Xavier Leroy for providing the idea of tactic <span class="inlinecode"><span class="id" type="var">forward</span></span>

</li>
<li> thanks to Georges Gonthier for the implementation trick in <span class="inlinecode"><span class="id" type="var">rapply</span></span>

</li>
</ul>

</div>
<div class="code code-tight">

<span class="id" type="keyword">Set</span> <span class="id" type="keyword">Implicit</span> <span class="id" type="var">Arguments</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">List</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;Very&nbsp;important&nbsp;to&nbsp;remove&nbsp;hint&nbsp;trans_eq_bool&nbsp;from&nbsp;LibBool,<br/>
&nbsp;&nbsp;&nbsp;otherwise&nbsp;eauto&nbsp;slows&nbsp;down&nbsp;dramatically:<br/>
&nbsp;&nbsp;Lemma&nbsp;test&nbsp;:&nbsp;forall&nbsp;b,&nbsp;b&nbsp;=&nbsp;false.<br/>
&nbsp;&nbsp;time&nbsp;eauto&nbsp;7.&nbsp;<span class="comment">(*&nbsp;takes&nbsp;over&nbsp;4&nbsp;seconds&nbsp;&nbsp;to&nbsp;fail!&nbsp;*)</span>&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="var">Remove</span> <span class="id" type="var">Hints</span> <span class="id" type="var">Bool.trans_eq_bool</span>.<br/>
</div>

<div class="doc">
<a name="lab453"></a><h1 class="section">Tools for Programming with Ltac</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab454"></a><h2 class="section">Identity Continuation</h2>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">idcont</span> <span class="id" type="var">tt</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">idtac</span>.<br/>
</div>

<div class="doc">
<a name="lab455"></a><h2 class="section">Untyped Arguments for Tactics</h2>

<div class="paragraph"> </div>

 Any Coq value can be boxed into the type <span class="inlinecode"><span class="id" type="var">Boxer</span></span>. This is
    useful to use Coq computations for implementing tactics. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">Boxer</span> : <span class="id" type="keyword">Type</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">boxer</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">A</span>:<span class="id" type="keyword">Type</span>), <span class="id" type="var">A</span> → <span class="id" type="var">Boxer</span>.<br/>
</div>

<div class="doc">
<a name="lab456"></a><h2 class="section">Optional Arguments for Tactics</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">ltac_no_arg</span></span> is a constant that can be used to simulate
    optional arguments in tactic definitions.
    Use <span class="inlinecode"><span class="id" type="var">mytactic</span></span> <span class="inlinecode"><span class="id" type="var">ltac_no_arg</span></span> on the tactic invokation,
    and use <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode"><span class="id" type="var">arg</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">ltac_no_arg</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode">..</span> or
    <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode"><span class="id" type="var">type</span></span> <span class="inlinecode"><span class="id" type="var">of</span></span> <span class="inlinecode"><span class="id" type="var">arg</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">ltac_No_arg</span></span>  <span class="inlinecode">⇒</span> <span class="inlinecode">..</span> to
    test whether an argument was provided. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">ltac_No_arg</span> : <span class="id" type="keyword">Set</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_no_arg</span> : <span class="id" type="var">ltac_No_arg</span>.<br/>
</div>

<div class="doc">
<a name="lab457"></a><h2 class="section">Wildcard Arguments for Tactics</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">ltac_wild</span></span> is a constant that can be used to simulate
    wildcard arguments in tactic definitions. Notation is <span class="inlinecode"><span class="id" type="var">__</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">ltac_Wild</span> : <span class="id" type="keyword">Set</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_wild</span> : <span class="id" type="var">ltac_Wild</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> "'__'" := <span class="id" type="var">ltac_wild</span> : <span class="id" type="var">ltac_scope</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">ltac_wilds</span></span> is another constant that is typically used to
    simulate a sequence of <span class="inlinecode"><span class="id" type="var">N</span></span> wildcards, with <span class="inlinecode"><span class="id" type="var">N</span></span> chosen
    appropriately depending on the context. Notation is <span class="inlinecode"><span class="id" type="var">___</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">ltac_Wilds</span> : <span class="id" type="keyword">Set</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_wilds</span> : <span class="id" type="var">ltac_Wilds</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> "'___'" := <span class="id" type="var">ltac_wilds</span> : <span class="id" type="var">ltac_scope</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Open</span> <span class="id" type="keyword">Scope</span> <span class="id" type="var">ltac_scope</span>.<br/>
</div>

<div class="doc">
<a name="lab458"></a><h2 class="section">Position Markers</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">ltac_Mark</span></span> and <span class="inlinecode"><span class="id" type="var">ltac_mark</span></span> are dummy definitions used as sentinel
    by tactics, to mark a certain position in the context or in the goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">ltac_Mark</span> : <span class="id" type="keyword">Type</span> :=<br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_mark</span> : <span class="id" type="var">ltac_Mark</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">gen_until_mark</span></span> repeats <span class="inlinecode"><span class="id" type="tactic">generalize</span></span> on hypotheses from the
    context, starting from the bottom and stopping as soon as reaching
    an hypothesis of type <span class="inlinecode"><span class="id" type="var">Mark</span></span>. If fails if <span class="inlinecode"><span class="id" type="var">Mark</span></span> does not
    appear in the context. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">gen_until_mark</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_Mark</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">generalize</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="var">gen_until_mark</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">gen_until_mark_with_processing</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> is similar to <span class="inlinecode"><span class="id" type="var">gen_until_mark</span></span>
    except that it calls <span class="inlinecode"><span class="id" type="var">F</span></span> on each hypothesis immediately before
    generalizing it. This is useful for processing the hypotheses. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">gen_until_mark_with_processing</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_Mark</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">cont</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">generalize</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">gen_until_mark_with_processing</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">intro_until_mark</span></span> repeats <span class="inlinecode"><span class="id" type="tactic">intro</span></span> until reaching an hypothesis of
    type <span class="inlinecode"><span class="id" type="var">Mark</span></span>. It throws away the hypothesis <span class="inlinecode"><span class="id" type="var">Mark</span></span>.
    It fails if <span class="inlinecode"><span class="id" type="var">Mark</span></span> does not appear as an hypothesis in the
    goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">intro_until_mark</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">ltac_Mark</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="tactic">intros</span> <span class="id" type="var">_</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">intro</span>; <span class="id" type="var">intro_until_mark</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab459"></a><h2 class="section">List of Arguments for Tactics</h2>

<div class="paragraph"> </div>

 A datatype of type <span class="inlinecode"><span class="id" type="var">list</span></span> <span class="inlinecode"><span class="id" type="var">Boxer</span></span> is used to manipulate list of
    Coq values in ltac. Notation is <span class="inlinecode">&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">v<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">v<sub>2</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">vN</span></span> for building
    a list containing the values <span class="inlinecode"><span class="id" type="var">v<sub>1</sub></span></span> through <span class="inlinecode"><span class="id" type="var">vN</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Notation</span> "'&gt;&gt;'" :=<br/>
&nbsp;&nbsp;(@<span class="id" type="var">nil</span> <span class="id" type="var">Boxer</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub> v<sub>8</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>8</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>8</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub> v<sub>8</sub> v<sub>9</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>8</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>9</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>8</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>9</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub> v<sub>8</sub> v<sub>9</sub> v<sub>10</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>8</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>9</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>10</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>8</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>9</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>10</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub> v<sub>8</sub> v<sub>9</sub> v<sub>10</sub> v<sub>11</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>8</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>9</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>10</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>11</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>8</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>9</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>10</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>11</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub> v<sub>8</sub> v<sub>9</sub> v<sub>10</sub> v<sub>11</sub> v<sub>12</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>8</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>9</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>10</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>11</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>12</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>8</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>9</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>10</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>11</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>12</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
<span class="id" type="keyword">Notation</span> "'&gt;&gt;' v<sub>1</sub> v<sub>2</sub> v<sub>3</sub> v<sub>4</sub> v<sub>5</sub> v<sub>6</sub> v<sub>7</sub> v<sub>8</sub> v<sub>9</sub> v<sub>10</sub> v<sub>11</sub> v<sub>12</sub> v<sub>13</sub>" :=<br/>
&nbsp;&nbsp;((<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>1</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>2</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>3</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>4</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>5</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>6</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>7</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>8</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>9</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>10</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>11</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>12</sub></span>)::(<span class="id" type="var">boxer</span> <span class="id" type="var">v<sub>13</sub></span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>1</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>2</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>3</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>4</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>5</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>6</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>7</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>8</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>9</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>10</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>11</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0,<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">v<sub>12</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">v<sub>13</sub></span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0)<br/>
&nbsp;&nbsp;: <span class="id" type="var">ltac_scope</span>.<br/>
</div>

<div class="doc">
The tactic <span class="inlinecode"><span class="id" type="var">list_boxer_of</span></span> inputs a term <span class="inlinecode"><span class="id" type="var">E</span></span> and returns a term
    of type "list boxer", according to the following rules:

<div class="paragraph"> </div>

<ul class="doclist">
<li> if <span class="inlinecode"><span class="id" type="var">E</span></span> is already of type "list Boxer", then it returns <span class="inlinecode"><span class="id" type="var">E</span></span>;

</li>
<li> otherwise, it returns the list <span class="inlinecode">(<span class="id" type="var">boxer</span></span> <span class="inlinecode"><span class="id" type="var">E</span>)::<span class="id" type="var">nil</span></span>. 
</li>
</ul>

</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">List.list</span> <span class="id" type="var">Boxer</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">E</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">boxer</span> <span class="id" type="var">E</span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab460"></a><h2 class="section">Databases of Lemmas</h2>

<div class="paragraph"> </div>

 Use the hint facility to implement a database mapping
    terms to terms. To declare a new database, use a definition:
    <span class="inlinecode"><span class="id" type="keyword">Definition</span></span> <span class="inlinecode"><span class="id" type="var">mydatabase</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">True</span>.</span>

<div class="paragraph"> </div>

    Then, to map <span class="inlinecode"><span class="id" type="var">mykey</span></span> to <span class="inlinecode"><span class="id" type="var">myvalue</span></span>, write the hint:
    <span class="inlinecode"><span class="id" type="keyword">Hint</span></span> <span class="inlinecode"><span class="id" type="keyword">Extern</span></span> <span class="inlinecode">1</span> <span class="inlinecode">(<span class="id" type="var">Register</span></span> <span class="inlinecode"><span class="id" type="var">mydatabase</span></span> <span class="inlinecode"><span class="id" type="var">mykey</span>)</span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">Provide</span></span> <span class="inlinecode"><span class="id" type="var">myvalue</span>.</span>

<div class="paragraph"> </div>

    Finally, to query the value associated with a key, run the
    tactic <span class="inlinecode"><span class="id" type="var">ltac_database_get</span></span> <span class="inlinecode"><span class="id" type="var">mydatabase</span></span> <span class="inlinecode"><span class="id" type="var">mykey</span></span>. This will leave
    at the head of the goal the term <span class="inlinecode"><span class="id" type="var">myvalue</span></span>. It can then be
    named and exploited using <span class="inlinecode"><span class="id" type="tactic">intro</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">Ltac_database_token</span> : <span class="id" type="keyword">Prop</span> := <span class="id" type="var">ltac_database_token</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">ltac_database</span> (<span class="id" type="var">D</span>:<span class="id" type="var">Boxer</span>) (<span class="id" type="var">T</span>:<span class="id" type="var">Boxer</span>) (<span class="id" type="var">A</span>:<span class="id" type="var">Boxer</span>) := <span class="id" type="var">Ltac_database_token</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> "'Register' D T" := (<span class="id" type="var">ltac_database</span> (<span class="id" type="var">boxer</span> <span class="id" type="var">D</span>) (<span class="id" type="var">boxer</span> <span class="id" type="var">T</span>) <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 69, <span class="id" type="var">D</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0, <span class="id" type="var">T</span> <span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 0).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">ltac_database_provide</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">A</span>:<span class="id" type="var">Boxer</span>) (<span class="id" type="var">D</span>:<span class="id" type="var">Boxer</span>) (<span class="id" type="var">T</span>:<span class="id" type="var">Boxer</span>),<br/>
&nbsp;&nbsp;<span class="id" type="var">ltac_database</span> <span class="id" type="var">D</span> <span class="id" type="var">T</span> <span class="id" type="var">A</span>.<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>. <span class="id" type="tactic">split</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">Provide</span> <span class="id" type="var">T</span> := <span class="id" type="tactic">apply</span> (@<span class="id" type="var">ltac_database_provide</span> (<span class="id" type="var">boxer</span> <span class="id" type="var">T</span>)).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">ltac_database_get</span> <span class="id" type="var">D</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">A</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">evar</span> (<span class="id" type="var">A</span>:<span class="id" type="var">Boxer</span>);<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">H</span> : <span class="id" type="var">ltac_database</span> (<span class="id" type="var">boxer</span> <span class="id" type="var">D</span>) (<span class="id" type="var">boxer</span> <span class="id" type="var">T</span>) <span class="id" type="var">A</span>);<br/>
&nbsp;&nbsp;[ <span class="id" type="tactic">subst</span> <span class="id" type="var">A</span>; <span class="id" type="tactic">auto</span><br/>
&nbsp;&nbsp;| <span class="id" type="tactic">subst</span> <span class="id" type="var">A</span>; <span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> <span class="id" type="var">ltac_database</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> (<span class="id" type="var">boxer</span> ?<span class="id" type="var">L</span>) ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">L</span> <span class="id" type="keyword">end</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> ].<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;Note&nbsp;for&nbsp;a&nbsp;possible&nbsp;alternative&nbsp;implementation&nbsp;of&nbsp;the&nbsp;ltac_database_token:<br/>
&nbsp;&nbsp;&nbsp;Inductive&nbsp;Ltac_database&nbsp;:&nbsp;Type&nbsp;:=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ltac_database&nbsp;:&nbsp;forall&nbsp;A,&nbsp;A&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;Ltac_database.<br/>
&nbsp;&nbsp;&nbsp;Implicit&nbsp;Arguments&nbsp;ltac_database&nbsp;<span class="inlinecode"><span class="id" type="var">A</span></span>.<br/>
*)</span><br/>
</div>

<div class="doc">
<a name="lab461"></a><h2 class="section">On-the-Fly Removal of Hypotheses</h2>

<div class="paragraph"> </div>

 In a list of arguments <span class="inlinecode">&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">H<sub>2</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">HN</span></span> passed to a tactic
    such as <span class="inlinecode"><span class="id" type="var">lets</span></span> or <span class="inlinecode"><span class="id" type="var">applys</span></span> or <span class="inlinecode"><span class="id" type="var">forwards</span></span> or <span class="inlinecode"><span class="id" type="var">specializes</span></span>,
    the term <span class="inlinecode"><span class="id" type="var">rm</span></span>, an identity function, can be placed in front
    of the name of an hypothesis to be deleted. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">rm</span> (<span class="id" type="var">A</span>:<span class="id" type="keyword">Type</span>) (<span class="id" type="var">X</span>:<span class="id" type="var">A</span>) := <span class="id" type="var">X</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">rm_term</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> removes one hypothesis that admits the same
    type as <span class="inlinecode"><span class="id" type="var">E</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">rm_term</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: <span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">try</span> <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">rm_inside</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> calls <span class="inlinecode"><span class="id" type="var">rm_term</span></span> <span class="inlinecode"><span class="id" type="var">Ei</span></span> for any subterm
    of the form <span class="inlinecode"><span class="id" type="var">rm</span></span> <span class="inlinecode"><span class="id" type="var">Ei</span></span> found in E 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">rm_inside</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">go</span> <span class="id" type="var">E</span> := <span class="id" type="var">rm_inside</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">rm</span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">rm_term</span> <span class="id" type="var">X</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>5</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>6</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ?<span class="id" type="var">X<sub>7</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>7</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ?<span class="id" type="var">X<sub>7</sub></span> ?<span class="id" type="var">X<sub>8</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>8</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ?<span class="id" type="var">X<sub>7</sub></span> ?<span class="id" type="var">X<sub>8</sub></span> ?<span class="id" type="var">X<sub>9</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>8</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>9</sub></span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ?<span class="id" type="var">X<sub>7</sub></span> ?<span class="id" type="var">X<sub>8</sub></span> ?<span class="id" type="var">X<sub>9</sub></span> ?<span class="id" type="var">X<sub>10</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>8</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>9</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">X<sub>10</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
For faster performance, one may deactivate <span class="inlinecode"><span class="id" type="var">rm_inside</span></span> by
    replacing the body of this definition with <span class="inlinecode"><span class="id" type="var">idtac</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">fast_rm_inside</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rm_inside</span> <span class="id" type="var">E</span>.<br/>
</div>

<div class="doc">
<a name="lab462"></a><h2 class="section">Numbers as Arguments</h2>

<div class="paragraph"> </div>

 When tactic takes a natural number as argument, it may be
    parsed either as a natural number or as a relative number.
    In order for tactics to convert their arguments into natural numbers,
    we provide a conversion tactic. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Require</span> <span class="id" type="var">BinPos</span> <span class="id" type="var">Coq.ZArith.BinInt</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Require</span> <span class="id" type="var">Coq.Numbers.BinNums</span> <span class="id" type="var">Coq.ZArith.BinInt</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">ltac_int_to_nat</span> (<span class="id" type="var">x</span>:<span class="id" type="var">BinInt.Z</span>) : <span class="id" type="var">nat</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">x</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">BinInt.Z0</span> ⇒ 0%<span class="id" type="var">nat</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">BinInt.Zpos</span> <span class="id" type="var">p</span> ⇒ <span class="id" type="var">BinPos.nat_of_P</span> <span class="id" type="var">p</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">BinInt.Zneg</span> <span class="id" type="var">p</span> ⇒ 0%<span class="id" type="var">nat</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">nat</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">N</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">BinInt.Z</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">N'</span> := <span class="id" type="var">constr</span>:(<span class="id" type="var">ltac_int_to_nat</span> <span class="id" type="var">N</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">eval</span> <span class="id" type="tactic">compute</span> <span class="id" type="keyword">in</span> <span class="id" type="var">N'</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">ltac_pattern</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">pattern</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> except that
    <span class="inlinecode"><span class="id" type="var">K</span></span> is a Coq number (nat or Z) rather than a Ltac integer. Syntax
    <span class="inlinecode"><span class="id" type="var">ltac_pattern</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "ltac_pattern" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">K</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 1 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 1<br/>
&nbsp;&nbsp;| 2 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 2<br/>
&nbsp;&nbsp;| 3 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 3<br/>
&nbsp;&nbsp;| 4 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 4<br/>
&nbsp;&nbsp;| 5 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 5<br/>
&nbsp;&nbsp;| 6 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 6<br/>
&nbsp;&nbsp;| 7 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 7<br/>
&nbsp;&nbsp;| 8 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 8<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">fail</span> "ltac_pattern: arity not supported"<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "ltac_pattern" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">K</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 1 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 1 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 2 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 2 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 3 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 3 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 4 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 4 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 5 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 5 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 6 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 6 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 7 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 7 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| 8 ⇒ <span class="id" type="tactic">pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> 8 <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">fail</span> "ltac_pattern: arity not supported"<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">ltac_set</span></span> <span class="inlinecode">(<span class="id" type="var">x</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">E</span>)</span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">set</span></span> <span class="inlinecode">(<span class="id" type="var">x</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">E</span>)</span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> except
    that <span class="inlinecode"><span class="id" type="var">K</span></span> is a Coq number (nat or Z) rather than a Ltac integer. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "ltac_set" "(" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":=" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) ")" "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">K</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 1%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 1<br/>
&nbsp;&nbsp;| 2%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 2<br/>
&nbsp;&nbsp;| 3%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 3<br/>
&nbsp;&nbsp;| 4%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 4<br/>
&nbsp;&nbsp;| 5%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 5<br/>
&nbsp;&nbsp;| 6%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 6<br/>
&nbsp;&nbsp;| 7%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 7<br/>
&nbsp;&nbsp;| 8%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 8<br/>
&nbsp;&nbsp;| 9%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 9<br/>
&nbsp;&nbsp;| 10%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 10<br/>
&nbsp;&nbsp;| 11%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 11<br/>
&nbsp;&nbsp;| 12%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 12<br/>
&nbsp;&nbsp;| 13%<span class="id" type="var">nat</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="tactic">at</span> 13<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">fail</span> "ltac_set: arity not supported"<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab463"></a><h2 class="section">Testing Tactics</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">show</span></span> <span class="inlinecode"><span class="id" type="var">tac</span></span> executes a tactic <span class="inlinecode"><span class="id" type="var">tac</span></span> that produces a result,
    and then display its result. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "show" <span class="id" type="var">tactic</span>(<span class="id" type="var">tac</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">R</span> := <span class="id" type="var">tac</span> <span class="id" type="keyword">in</span> <span class="id" type="var">pose</span> <span class="id" type="var">R</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">dup</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> produces <span class="inlinecode"><span class="id" type="var">N</span></span> copies of the current goal. It is useful
    for building examples on which to illustrate behaviour of tactics.
    <span class="inlinecode"><span class="id" type="var">dup</span></span> is short for <span class="inlinecode"><span class="id" type="var">dup</span></span> <span class="inlinecode">2</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">dup_lemma</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">P</span>, <span class="id" type="var">P</span> → <span class="id" type="var">P</span> → <span class="id" type="var">P</span>.<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">dup_tactic</span> <span class="id" type="var">N</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 0 ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">S</span> 0 ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">S</span> ?<span class="id" type="var">N'</span> ⇒ <span class="id" type="tactic">apply</span> <span class="id" type="var">dup_lemma</span>; [ | <span class="id" type="var">dup_tactic</span> <span class="id" type="var">N'</span> ]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "dup" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">dup_tactic</span> <span class="id" type="var">N</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "dup" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">dup</span> 2.<br/>
</div>

<div class="doc">
<a name="lab464"></a><h2 class="section">Testing evars and non-evars</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">is_not_evar</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> succeeds only if <span class="inlinecode"><span class="id" type="var">E</span></span> is not an evar;
    it fails otherwise. It thus implements the negation of <span class="inlinecode"><span class="id" type="var">is_evar</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">is_not_evar</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="var">is_evar</span> <span class="id" type="var">E</span>; <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">idtac</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">is_evar_as_bool</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> evaluates to <span class="inlinecode"><span class="id" type="var">true</span></span> if <span class="inlinecode"><span class="id" type="var">E</span></span> is an evar
    and to <span class="inlinecode"><span class="id" type="var">false</span></span> otherwise. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">is_evar_as_bool</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">constr</span>:(<span class="id" type="var">ltac</span>:(<span class="id" type="var">first</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;[ <span class="id" type="var">is_evar</span> <span class="id" type="var">E</span>; <span class="id" type="tactic">exact</span> <span class="id" type="var">true</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">exact</span> <span class="id" type="var">false</span> ])).<br/>
</div>

<div class="doc">
<a name="lab465"></a><h2 class="section">Check No Evar in Goal</h2>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">check_noevar</span> <span class="id" type="var">M</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="var">has_evar</span> <span class="id" type="var">M</span>; <span class="id" type="tactic">fail</span> 2 | <span class="id" type="var">idtac</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">check_noevar_hyp</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">in</span> <span class="id" type="var">check_noevar</span> <span class="id" type="var">T</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">check_noevar_goal</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">G</span> ⇒ <span class="id" type="var">check_noevar</span> <span class="id" type="var">G</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab466"></a><h2 class="section">Helper Function for Introducing Evars</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">with_evar</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode">(<span class="id" type="keyword">fun</span></span> <span class="inlinecode"><span class="id" type="var">M</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">tac</span>)</span> creates a new evar that can
    be used in the tactic <span class="inlinecode"><span class="id" type="var">tac</span></span> under the name <span class="inlinecode"><span class="id" type="var">M</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">with_evar_base</span> <span class="id" type="var">T</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">x</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">evar</span> (<span class="id" type="var">x</span>:<span class="id" type="var">T</span>); <span class="id" type="var">cont</span> <span class="id" type="var">x</span>; <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "with_evar" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) <span class="id" type="var">tactic</span>(<span class="id" type="var">cont</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">with_evar_base</span> <span class="id" type="var">T</span> <span class="id" type="var">cont</span>.<br/>
</div>

<div class="doc">
<a name="lab467"></a><h2 class="section">Tagging of Hypotheses</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">get_last_hyp</span></span> <span class="inlinecode"><span class="id" type="var">tt</span></span> is a function that returns the last hypothesis
    at the bottom of the context. It is useful to obtain the default
    name associated with the hypothesis, e.g.
    <span class="inlinecode"><span class="id" type="tactic">intro</span>;</span> <span class="inlinecode"><span class="id" type="keyword">let</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">get_last_hyp</span></span> <span class="inlinecode"><span class="id" type="var">tt</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="keyword">let</span></span> <span class="inlinecode"><span class="id" type="var">H'</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="tactic">fresh</span></span> <span class="inlinecode">"<span class="id" type="var">P</span>"</span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">...</span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_last_hyp</span> <span class="id" type="var">tt</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">H</span>) <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab468"></a><h2 class="section">More Tagging of Hypotheses</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">ltac_tag_subst</span></span> is a specific marker for hypotheses
    which is used to tag hypotheses that are equalities to
    be substituted. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">ltac_tag_subst</span> (<span class="id" type="var">A</span>:<span class="id" type="keyword">Type</span>) (<span class="id" type="var">x</span>:<span class="id" type="var">A</span>) := <span class="id" type="var">x</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">ltac_to_generalize</span></span> is a specific marker for hypotheses
    to be generalized. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">ltac_to_generalize</span> (<span class="id" type="var">A</span>:<span class="id" type="keyword">Type</span>) (<span class="id" type="var">x</span>:<span class="id" type="var">A</span>) := <span class="id" type="var">x</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">gen_to_generalize</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">H</span>: <span class="id" type="var">ltac_to_generalize</span> <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">generalize</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">mark_to_generalize</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">change</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">ltac_to_generalize</span> <span class="id" type="var">T</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<a name="lab469"></a><h2 class="section">Deconstructing Terms</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">get_head</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a tactic that returns the head constant of the
    term <span class="inlinecode"><span class="id" type="var">E</span></span>, ie, when applied to a term of the form <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">xN</span></span>
    it returns <span class="inlinecode"><span class="id" type="var">P</span></span>. If <span class="inlinecode"><span class="id" type="var">E</span></span> is not an application, it returns <span class="inlinecode"><span class="id" type="var">E</span></span>.
    Warning: the tactic seems to loop in some cases when the goal is
    a product and one uses the result of this function. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_head</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">P</span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">get_fun_arg</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a tactic that decomposes an application
  term <span class="inlinecode"><span class="id" type="var">E</span></span>, ie, when applied to a term of the form <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">XN</span></span>
  it returns a pair made of <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">X</span>(<span class="id" type="var">N</span>-1)</span> and <span class="inlinecode"><span class="id" type="var">XN</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_fun_arg</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ?<span class="id" type="var">X<sub>7</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">X<sub>6</sub></span> <span class="id" type="var">X<sub>7</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X<sub>6</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">X<sub>6</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X<sub>5</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X<sub>4</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X<sub>3</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X<sub>2</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">X<sub>1</sub></span> ?<span class="id" type="var">X</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">X<sub>1</sub></span>,<span class="id" type="var">X</span>))<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab470"></a><h2 class="section">Action at Occurence and Action Not at Occurence</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">ltac_action_at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="var">of</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">do</span></span> <span class="inlinecode"><span class="id" type="var">Tac</span></span> isolates the <span class="inlinecode"><span class="id" type="var">K</span></span>-th occurence of <span class="inlinecode"><span class="id" type="var">E</span></span> in the
    goal, setting it in the form <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> for some named pattern <span class="inlinecode"><span class="id" type="var">P</span></span>,
    then calls tactic <span class="inlinecode"><span class="id" type="var">Tac</span></span>, and finally unfolds <span class="inlinecode"><span class="id" type="var">P</span></span>. Syntax
    <span class="inlinecode"><span class="id" type="var">ltac_action_at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="var">of</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="tactic">do</span></span> <span class="inlinecode"><span class="id" type="var">Tac</span></span> is also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "ltac_action_at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "of" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "do" <span class="id" type="var">tactic</span>(<span class="id" type="var">Tac</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">p</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">ltac_pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> <span class="id" type="var">K</span>;<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">p</span>:=<span class="id" type="var">P</span>) <span class="id" type="keyword">end</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">Tac</span>; <span class="id" type="tactic">unfold</span> <span class="id" type="var">p</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">p</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "ltac_action_at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "of" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "do" <span class="id" type="var">tactic</span>(<span class="id" type="var">Tac</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">p</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">ltac_pattern</span> <span class="id" type="var">E</span> <span class="id" type="tactic">at</span> <span class="id" type="var">K</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">P</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">set</span> (<span class="id" type="var">p</span>:=<span class="id" type="var">P</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">Tac</span>; <span class="id" type="tactic">unfold</span> <span class="id" type="var">p</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">p</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">protects</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">do</span></span> <span class="inlinecode"><span class="id" type="var">Tac</span></span> temporarily assigns a name to the expression <span class="inlinecode"><span class="id" type="var">E</span></span>
    so that the execution of tactic <span class="inlinecode"><span class="id" type="var">Tac</span></span> will not modify <span class="inlinecode"><span class="id" type="var">E</span></span>. This is
    useful for instance to restrict the action of <span class="inlinecode"><span class="id" type="tactic">simpl</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "protects" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "do" <span class="id" type="var">tactic</span>(<span class="id" type="var">Tac</span>) :=<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;let&nbsp;x&nbsp;:=&nbsp;fresh&nbsp;"TEMP"&nbsp;in&nbsp;sets_eq&nbsp;x:&nbsp;E;&nbsp;T;&nbsp;subst&nbsp;x.&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">x</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> *; <span class="id" type="tactic">assert</span> (<span class="id" type="var">H</span> : <span class="id" type="var">X</span> = <span class="id" type="var">E</span>) <span class="id" type="tactic">by</span> <span class="id" type="tactic">reflexivity</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">clearbody</span> <span class="id" type="var">X</span>; <span class="id" type="var">Tac</span>; <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "protects" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "do" <span class="id" type="var">tactic</span>(<span class="id" type="var">Tac</span>) "/" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">protects</span> <span class="id" type="var">E</span> <span class="id" type="tactic">do</span> <span class="id" type="var">Tac</span>.<br/>
</div>

<div class="doc">
<a name="lab471"></a><h2 class="section">An Alias for <span class="inlinecode"><span class="id" type="var">eq</span></span></h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">eq'</span></span> is an alias for <span class="inlinecode"><span class="id" type="var">eq</span></span> to be used for equalities in
    inductive definitions, so that they don't get mixed with
    equalities generated by <span class="inlinecode"><span class="id" type="tactic">inversion</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">eq'</span> := @<span class="id" type="var">eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Hint</span> <span class="id" type="keyword">Unfold</span> <span class="id" type="var">eq'</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> "x '='' y" := (@<span class="id" type="var">eq'</span> <span class="id" type="var">_</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 70, <span class="id" type="var">y</span> <span class="id" type="tactic">at</span> <span class="id" type="var">next</span> <span class="id" type="var">level</span>).<br/>
</div>

<div class="doc">
<a name="lab472"></a><h1 class="section">Common Tactics for Simplifying Goals Like <span class="inlinecode"><span class="id" type="tactic">intuition</span></span></h1>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">jauto_set_hyps</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">a</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">generalize</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">jauto_set_goal</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">a</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">esplit</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">split</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">jauto_set</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span>; <span class="id" type="var">jauto_set_hyps</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span>; <span class="id" type="var">jauto_set_goal</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">not</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<a name="lab473"></a><h1 class="section">Backward and Forward Chaining</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab474"></a><h2 class="section">Application</h2>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">old_refine</span> <span class="id" type="var">f</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">refine</span> <span class="id" type="var">f</span>. <span class="comment">(*&nbsp;;&nbsp;shelve_unifiable.&nbsp;*)</span><br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">rapply</span></span> is a tactic similar to <span class="inlinecode"><span class="id" type="tactic">eapply</span></span> except that it is
    based on the <span class="inlinecode"><span class="id" type="tactic">refine</span></span> tactics, and thus is strictly more
    powerful (at least in theory :). In short, it is able to perform
    on-the-fly conversions when required for arguments to match,
    and it is able to instantiate existentials when required. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "rapply" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span>  <span class="comment">(*&nbsp;--TODO:&nbsp;the&nbsp;@&nbsp;are&nbsp;not&nbsp;useful&nbsp;*)</span><br/>
&nbsp;&nbsp;[ <span class="id" type="var">eexact</span> (@<span class="id" type="var">t</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>)<br/>
&nbsp;&nbsp;].<br/>
</div>

<div class="doc">
The tactics <span class="inlinecode"><span class="id" type="var">applys_N</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span>, where <span class="inlinecode"><span class="id" type="var">N</span></span> is a natural number,
    provides a more efficient way of using <span class="inlinecode"><span class="id" type="var">applys</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span>. It avoids
    trying out all possible arities, by specifying explicitely
    the arity of function <span class="inlinecode"><span class="id" type="var">T</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "rapply_0" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_1" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_2" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_3" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_4" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_5" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_6" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_7" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_8" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_9" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rapply_10" <span class="id" type="var">constr</span>(<span class="id" type="var">t</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">old_refine</span> (@<span class="id" type="var">t</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">lets_base</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> adds an hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode">:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> to the context, where <span class="inlinecode"><span class="id" type="var">T</span></span> is
    the type of term <span class="inlinecode"><span class="id" type="var">E</span></span>. If <span class="inlinecode"><span class="id" type="var">H</span></span> is an introduction pattern, it will
    destruct <span class="inlinecode"><span class="id" type="var">H</span></span> according to the pattern. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">lets_base</span> <span class="id" type="var">I</span> <span class="id" type="var">E</span> := <span class="id" type="tactic">generalize</span> <span class="id" type="var">E</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">I</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">applys_to</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> transform the type of hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span> by
    replacing it by the result of the application of the term
    <span class="inlinecode"><span class="id" type="var">E</span></span> to <span class="inlinecode"><span class="id" type="var">H</span></span>. Intuitively, it is equivalent to <span class="inlinecode"><span class="id" type="var">lets</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode">(<span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">H</span>)</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "applys_to" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H'</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">rename</span> <span class="id" type="var">H</span> <span class="id" type="var">into</span> <span class="id" type="var">H'</span>;<br/>
&nbsp;&nbsp;(<span class="id" type="var">first</span> [ <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">lets_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">E</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> <span class="id" type="var">H'</span>) ]<br/>
&nbsp;&nbsp;); <span class="id" type="tactic">clear</span> <span class="id" type="var">H'</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">applys_to</span></span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span>,...,<span class="id" type="var">HN</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> applys <span class="inlinecode"><span class="id" type="var">E</span></span> to several hypotheses 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "applys_to" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">E</span>; <span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_to" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) "," <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">E</span>; <span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">E</span>; <span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>3</sub></span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_to" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) "," <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>3</sub></span>) "," <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">E</span>; <span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">E</span>; <span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>3</sub></span> <span class="id" type="var">E</span>; <span class="id" type="var">applys_to</span> <span class="id" type="var">H<sub>4</sub></span> <span class="id" type="var">E</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">constructors</span></span> calls <span class="inlinecode"><span class="id" type="var">constructor</span></span> or <span class="inlinecode"><span class="id" type="var">econstructor</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "constructors" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="var">constructor</span> | <span class="id" type="var">econstructor</span> ]; <span class="id" type="tactic">unfold</span> <span class="id" type="var">eq'</span>.<br/>
</div>

<div class="doc">
<a name="lab475"></a><h2 class="section">Assertions</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is another syntax for <span class="inlinecode"><span class="id" type="tactic">assert</span></span> <span class="inlinecode">(<span class="id" type="var">H</span></span> <span class="inlinecode">:</span> <span class="inlinecode"><span class="id" type="var">T</span>)</span>, which
    also works with introduction patterns. For instance, one can write:
    <span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode">\[<span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">P</span>\]</span> <span class="inlinecode">(<span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">n</span>,</span> <span class="inlinecode"><span class="id" type="var">n</span></span> <span class="inlinecode">=</span> <span class="inlinecode">3)</span>, or
    <span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode">\[<span class="id" type="var">H</span>|<span class="id" type="var">H</span>\]</span> <span class="inlinecode">(<span class="id" type="var">n</span></span> <span class="inlinecode">=</span> <span class="inlinecode">0</span> <span class="inlinecode">∨</span> <span class="inlinecode"><span class="id" type="var">n</span></span> <span class="inlinecode">=</span> <span class="inlinecode">1).</span> <span class="inlinecode"></span>
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "asserts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">assert</span> (<span class="id" type="var">H</span> : <span class="id" type="var">T</span>);<br/>
&nbsp;&nbsp;[ | <span class="id" type="tactic">generalize</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">I</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">HN</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is a shorthand for
    <span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode">\[<span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">\[<span class="id" type="var">H<sub>2</sub></span></span> <span class="inlinecode">\[..</span> <span class="inlinecode"><span class="id" type="var">HN</span>\]\]\]\</span>: T]. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "asserts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>]]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>]]]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> [<span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>]]]]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> [<span class="id" type="var">I<sub>4</sub></span> [<span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span>]]]]]: <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">asserts</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is <span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> with <span class="inlinecode"><span class="id" type="var">H</span></span> being chosen automatically. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "asserts" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">asserts</span> <span class="id" type="var">H</span> : <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cuts</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is the same as <span class="inlinecode"><span class="id" type="var">asserts</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> except that the two subgoals
    generated are swapped: the subgoal <span class="inlinecode"><span class="id" type="var">T</span></span> comes second. Note that contrary
    to <span class="inlinecode"><span class="id" type="tactic">cut</span></span>, it introduces the hypothesis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "cuts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">cut</span> (<span class="id" type="var">T</span>); [ <span class="id" type="tactic">intros</span> <span class="id" type="var">I</span> | <span class="id" type="var">idtac</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cuts</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is <span class="inlinecode"><span class="id" type="var">cuts</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> with <span class="inlinecode"><span class="id" type="var">H</span></span> being chosen automatically. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "cuts" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">cuts</span> <span class="id" type="var">H</span>: <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cuts</span></span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">HN</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is a shorthand for
    <span class="inlinecode"><span class="id" type="var">cuts</span></span> <span class="inlinecode">\[<span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">\[<span class="id" type="var">H<sub>2</sub></span></span> <span class="inlinecode">\[..</span> <span class="inlinecode"><span class="id" type="var">HN</span>\]\]\]\</span>: T]. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "cuts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>]]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>]]]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> [<span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>]]]]: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> [<span class="id" type="var">I<sub>4</sub></span> [<span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span>]]]]]: <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<a name="lab476"></a><h2 class="section">Instantiation and Forward-Chaining</h2>

<div class="paragraph"> </div>

 The instantiation tactics are used to instantiate a lemma <span class="inlinecode"><span class="id" type="var">E</span></span>
    (whose type is a product) on some arguments. The type of <span class="inlinecode"><span class="id" type="var">E</span></span> is
    made of implications and universal quantifications, e.g.
    <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">x</span>,</span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">y</span></span> <span class="inlinecode"><span class="id" type="var">z</span>,</span> <span class="inlinecode"><span class="id" type="var">Q</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y</span></span> <span class="inlinecode"><span class="id" type="var">z</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">R</span></span> <span class="inlinecode"><span class="id" type="var">z</span></span>.

<div class="paragraph"> </div>

    The first possibility is to provide arguments in order: first <span class="inlinecode"><span class="id" type="var">x</span></span>,
    then a proof of <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span>, then <span class="inlinecode"><span class="id" type="var">y</span></span> etc... In this mode, called "Args",
    all the arguments are to be provided. If a wildcard is provided
    (written <span class="inlinecode"><span class="id" type="var">__</span></span>), then an existential variable will be introduced in
    place of the argument.

<div class="paragraph"> </div>

    It is very convenient to give some arguments the lemma should be
    instantiated on, and let the tactic find out automatically where
    underscores should be insterted. Underscore arguments <span class="inlinecode"><span class="id" type="var">__</span></span> are
    interpret as follows: an underscore means that we want to skip the
    argument that has the same type as the next real argument provided
    (real means not an underscore). If there is no real argument after
    underscore, then the underscore is used for the first possible argument.

<div class="paragraph"> </div>

    The general syntax is <span class="inlinecode"><span class="id" type="var">tactic</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> where <span class="inlinecode"><span class="id" type="var">tactic</span></span> is
    the name of the tactic (possibly with some arguments) and <span class="inlinecode"><span class="id" type="var">Ei</span></span>
    are the arguments. Moreover, some tactics accept the syntax
    <span class="inlinecode"><span class="id" type="var">tactic</span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> as short for <span class="inlinecode"><span class="id" type="var">tactic</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> for
    values of <span class="inlinecode"><span class="id" type="var">N</span></span> up to 5.

<div class="paragraph"> </div>

    Finally, if the argument <span class="inlinecode"><span class="id" type="var">EN</span></span> given is a triple-underscore <span class="inlinecode"><span class="id" type="var">___</span></span>,
    then it is equivalent to providing a list of wildcards, with
    the appropriate number of wildcards. This means that all
    the remaining arguments of the lemma will be instantiated.
    Definitions in the conclusion are not unfolded in this case. 
</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;Underlying&nbsp;implementation&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">H</span> : <span class="id" type="var">P</span>); [ | <span class="id" type="var">cont</span>(<span class="id" type="var">t</span> <span class="id" type="var">H</span>); <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">x</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">evar</span> (<span class="id" type="var">x</span>:<span class="id" type="var">A</span>);<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">t'</span> := <span class="id" type="var">constr</span>:(<span class="id" type="var">t</span> <span class="id" type="var">x</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">t''</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">unfold</span> <span class="id" type="var">x</span> <span class="id" type="keyword">in</span> <span class="id" type="var">t'</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">subst</span> <span class="id" type="var">x</span>; <span class="id" type="var">cont</span> <span class="id" type="var">t''</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">app_arg</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">v</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">H</span> : <span class="id" type="var">P</span>); [ <span class="id" type="tactic">apply</span> <span class="id" type="var">v</span> | <span class="id" type="var">cont</span>(<span class="id" type="var">t</span> <span class="id" type="var">H</span>); <span class="id" type="tactic">try</span> <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">build_app_alls</span> <span class="id" type="var">t</span> <span class="id" type="var">final</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">t</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">t</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">final</span> <span class="id" type="var">t</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">t</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">boxerlist_next_type</span> <span class="id" type="var">vs</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">vs</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">nil</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">ltac_wild</span>)<br/>
&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> <span class="id" type="var">ltac_wild</span>)::?<span class="id" type="var">vs'</span> ⇒ <span class="id" type="var">boxerlist_next_type</span> <span class="id" type="var">vs'</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> <span class="id" type="var">ltac_wilds</span>)::_ ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">ltac_wild</span>)<br/>
&nbsp;&nbsp;| (@<span class="id" type="var">boxer</span> ?<span class="id" type="var">T</span> <span class="id" type="var">_</span>)::_ ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">T</span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;Note:&nbsp;refuse&nbsp;to&nbsp;instantiate&nbsp;a&nbsp;dependent&nbsp;hypothesis&nbsp;with&nbsp;a&nbsp;proposition;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;refuse&nbsp;to&nbsp;instantiate&nbsp;an&nbsp;argument&nbsp;of&nbsp;type&nbsp;Type&nbsp;with&nbsp;one&nbsp;that<br/>
&nbsp;&nbsp;&nbsp;&nbsp;does&nbsp;not&nbsp;have&nbsp;the&nbsp;type&nbsp;Type.<br/>
*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">build_app_hnts</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span> <span class="id" type="var">final</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">vs</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">nil</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">final</span> <span class="id" type="var">t</span> | <span class="id" type="tactic">fail</span> 1 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> <span class="id" type="var">ltac_wilds</span>)::_ ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">build_app_alls</span> <span class="id" type="var">t</span> <span class="id" type="var">final</span> | <span class="id" type="tactic">fail</span> 1 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> ?<span class="id" type="var">v</span>)::?<span class="id" type="var">vs'</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">cont</span> <span class="id" type="var">t'</span> := <span class="id" type="var">go</span> <span class="id" type="var">t'</span> <span class="id" type="var">vs</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">cont'</span> <span class="id" type="var">t'</span> := <span class="id" type="var">go</span> <span class="id" type="var">t'</span> <span class="id" type="var">vs'</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">t</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">eval</span> <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">v</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">ltac_wild</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="keyword">let</span> <span class="id" type="var">U</span> := <span class="id" type="var">boxerlist_next_type</span> <span class="id" type="var">vs'</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">U</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">ltac_wild</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont'</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont'</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span>  <span class="comment">(*&nbsp;should&nbsp;test&nbsp;T&nbsp;for&nbsp;unifiability&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">U</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">U</span> <span class="id" type="var">cont'</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:<span class="id" type="var">U</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">U</span> <span class="id" type="var">cont'</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 2 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_arg</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">v</span> <span class="id" type="var">cont'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:<span class="id" type="keyword">Type</span>, <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">v</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="keyword">Type</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">cont'</span> (<span class="id" type="var">t</span> <span class="id" type="var">v</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="keyword">Type</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="keyword">Type</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">V</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">v</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">V</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="keyword">Prop</span> ⇒  <span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">cont'</span> (<span class="id" type="var">t</span> <span class="id" type="var">v</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span>.<br/>
</div>

<div class="doc">
newer version : support for typeclasses 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">t'</span> := <span class="id" type="var">constr</span>:(<span class="id" type="var">t</span> <span class="id" type="var">_</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">cont</span> <span class="id" type="var">t'</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">build_app_alls</span> <span class="id" type="var">t</span> <span class="id" type="var">final</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">t</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">t</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">final</span> <span class="id" type="var">t</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">t</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">build_app_hnts</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span> <span class="id" type="var">final</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">vs</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">nil</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">final</span> <span class="id" type="var">t</span> | <span class="id" type="tactic">fail</span> 1 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> <span class="id" type="var">ltac_wilds</span>)::_ ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">build_app_alls</span> <span class="id" type="var">t</span> <span class="id" type="var">final</span> | <span class="id" type="tactic">fail</span> 1 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> ?<span class="id" type="var">v</span>)::?<span class="id" type="var">vs'</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">cont</span> <span class="id" type="var">t'</span> := <span class="id" type="var">go</span> <span class="id" type="var">t'</span> <span class="id" type="var">vs</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">cont'</span> <span class="id" type="var">t'</span> := <span class="id" type="var">go</span> <span class="id" type="var">t'</span> <span class="id" type="var">vs'</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">t</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">eval</span> <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">v</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">ltac_wild</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="keyword">let</span> <span class="id" type="var">U</span> := <span class="id" type="var">boxerlist_next_type</span> <span class="id" type="var">vs'</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">U</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">ltac_wild</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont'</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">cont'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span>  <span class="comment">(*&nbsp;should&nbsp;test&nbsp;T&nbsp;for&nbsp;unifiability&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">U</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">U</span> <span class="id" type="var">cont'</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:<span class="id" type="var">U</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">cont'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">U</span> <span class="id" type="var">cont'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont</span> | <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 2 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_arg</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">v</span> <span class="id" type="var">cont'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_assert</span> <span class="id" type="var">t</span> <span class="id" type="var">P</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:<span class="id" type="keyword">Type</span>, <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">v</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="keyword">Type</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">cont'</span> (<span class="id" type="var">t</span> <span class="id" type="var">v</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="keyword">Type</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="keyword">Type</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>, <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">V</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">v</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">V</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="keyword">Prop</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">cont'</span> (<span class="id" type="var">t</span> <span class="id" type="var">v</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_typeclass</span> <span class="id" type="var">t</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">app_evar</span> <span class="id" type="var">t</span> <span class="id" type="var">A</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 3 ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;use&nbsp;local&nbsp;function&nbsp;for&nbsp;first&nbsp;<span class="inlinecode">...</span>&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="comment">(*--old&nbsp;version<br/>
Ltac&nbsp;build_app_hnts&nbsp;t&nbsp;vs&nbsp;final&nbsp;:=<br/>
&nbsp;&nbsp;let&nbsp;rec&nbsp;go&nbsp;t&nbsp;vs&nbsp;:=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;match&nbsp;vs&nbsp;with<br/>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;nil&nbsp;=&gt;&nbsp;first&nbsp;<span class="inlinecode"></span> <span class="inlinecode"><span class="id" type="var">final</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">1</span> <span class="inlinecode"></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;(boxer&nbsp;ltac_wilds)::_&nbsp;=&gt;&nbsp;first&nbsp;<span class="inlinecode"></span> <span class="inlinecode"><span class="id" type="var">build_app_alls</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">final</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">1</span> <span class="inlinecode"></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;(boxer&nbsp;?v)::?vs'&nbsp;=&gt;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;cont&nbsp;t'&nbsp;:=&nbsp;go&nbsp;t'&nbsp;vs&nbsp;in<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;cont'&nbsp;t'&nbsp;:=&nbsp;go&nbsp;t'&nbsp;vs'&nbsp;in<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;T&nbsp;:=&nbsp;type&nbsp;of&nbsp;t&nbsp;in<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;T&nbsp;:=&nbsp;eval&nbsp;hnf&nbsp;in&nbsp;T&nbsp;in<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match&nbsp;v&nbsp;with<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;ltac_wild&nbsp;=&gt;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first&nbsp;<span class="inlinecode"></span> <span class="inlinecode"><span class="id" type="keyword">let</span></span> <span class="inlinecode"><span class="id" type="var">U</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">boxerlist_next_type</span></span> <span class="inlinecode"><span class="id" type="var">vs'</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span>
           <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode"><span class="id" type="var">U</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span>
           <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="var">ltac_wild</span></span> <span class="inlinecode">⇒</span>
             <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span>
             <span class="inlinecode">|</span> <span class="inlinecode">?<span class="id" type="var">P</span></span> <span class="inlinecode">→</span> <span class="inlinecode">?<span class="id" type="var">Q</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">app_assert</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">cont'</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode">]</span>
             <span class="inlinecode">|</span> <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>,</span> <span class="inlinecode"><span class="id" type="var">_</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">app_evar</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode"><span class="id" type="var">cont'</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode">]</span>
             <span class="inlinecode"><span class="id" type="keyword">end</span></span>
           <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="var">_</span></span> <span class="inlinecode">⇒</span>
             <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span>  <span class="inlinecode">&nbsp;should&nbsp;test&nbsp;T&nbsp;for&nbsp;unifiability&nbsp;*)</span><br/>
</span>             <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="var">U</span></span> <span class="inlinecode">→</span> <span class="inlinecode">?<span class="id" type="var">Q</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">app_assert</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">U</span></span> <span class="inlinecode"><span class="id" type="var">cont'</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode">]</span>
             <span class="inlinecode">|</span> <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">_</span>:<span class="id" type="var">U</span>,</span> <span class="inlinecode"><span class="id" type="var">_</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">app_evar</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">U</span></span> <span class="inlinecode"><span class="id" type="var">cont'</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode">]</span>
             <span class="inlinecode">|</span> <span class="inlinecode">?<span class="id" type="var">P</span></span> <span class="inlinecode">→</span> <span class="inlinecode">?<span class="id" type="var">Q</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">app_assert</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">cont</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode">]</span>
             <span class="inlinecode">|</span> <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">_</span>:?<span class="id" type="var">A</span>,</span> <span class="inlinecode"><span class="id" type="var">_</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">app_evar</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode"><span class="id" type="var">cont</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode">]</span>
             <span class="inlinecode"><span class="id" type="keyword">end</span></span>
           <span class="inlinecode"><span class="id" type="keyword">end</span></span>
         <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">2</span> <span class="inlinecode"></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;_&nbsp;=&gt;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;match&nbsp;T&nbsp;with<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;?P&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;?Q&nbsp;=&gt;&nbsp;first&nbsp;<span class="inlinecode"></span> <span class="inlinecode"><span class="id" type="var">app_arg</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">v</span></span> <span class="inlinecode"><span class="id" type="var">cont'</span></span>
                              <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="var">app_assert</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">cont</span></span>
                              <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode"></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;forall&nbsp;_:?A,&nbsp;_&nbsp;=&gt;&nbsp;first&nbsp;<span class="inlinecode"></span> <span class="inlinecode"><span class="id" type="var">cont'</span></span> <span class="inlinecode">(<span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">v</span>)</span>
                                    <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="var">app_evar</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode"><span class="id" type="var">cont</span></span>
                                    <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">fail</span></span> <span class="inlinecode">3</span> <span class="inlinecode"></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br/>
&nbsp;&nbsp;&nbsp;&nbsp;end&nbsp;in<br/>
&nbsp;&nbsp;go&nbsp;t&nbsp;vs.<br/>
*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">final</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">args</span> <span class="id" type="keyword">with</span> (@<span class="id" type="var">boxer</span> ?<span class="id" type="var">T</span> ?<span class="id" type="var">t</span>)::?<span class="id" type="var">vs</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">t</span> := <span class="id" type="var">constr</span>:(<span class="id" type="var">t</span>:<span class="id" type="var">T</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">build_app_hnts</span> <span class="id" type="var">t</span> <span class="id" type="var">vs</span> <span class="id" type="var">final</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">fast_rm_inside</span> <span class="id" type="var">args</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 1 "Instantiation fails for:" <span class="id" type="var">args</span>].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unfold_head_until_product</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">eval</span> <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">args_unfold_head_if_not_product</span> <span class="id" type="var">args</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">args</span> <span class="id" type="keyword">with</span> (@<span class="id" type="var">boxer</span> ?<span class="id" type="var">T</span> ?<span class="id" type="var">t</span>)::?<span class="id" type="var">vs</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T'</span> := <span class="id" type="var">unfold_head_until_product</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">constr</span>:((@<span class="id" type="var">boxer</span> <span class="id" type="var">T'</span> <span class="id" type="var">t</span>)::<span class="id" type="var">vs</span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">args_unfold_head_if_not_product_but_params</span> <span class="id" type="var">args</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">args</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> ?<span class="id" type="var">t</span>)::(<span class="id" type="var">boxer</span> ?<span class="id" type="var">v</span>)::?<span class="id" type="var">vs</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">args_unfold_head_if_not_product</span> <span class="id" type="var">args</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">args</span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">lets</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> will instantiate lemma <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span>
    on the arguments <span class="inlinecode"><span class="id" type="var">Ei</span></span> (which may be wildcards <span class="inlinecode"><span class="id" type="var">__</span></span>),
    and name <span class="inlinecode"><span class="id" type="var">H</span></span> the resulting term. <span class="inlinecode"><span class="id" type="var">H</span></span> may be an introduction
    pattern, or a sequence of introduction patterns <span class="inlinecode"><span class="id" type="var">I<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">I<sub>2</sub></span></span> <span class="inlinecode"><span class="id" type="var">IN</span></span>,
    or empty.
    Syntax <span class="inlinecode"><span class="id" type="var">lets</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> is also available. If the last
    argument <span class="inlinecode"><span class="id" type="var">EN</span></span> is <span class="inlinecode"><span class="id" type="var">___</span></span> (triple-underscore), then all
    arguments of <span class="inlinecode"><span class="id" type="var">H</span></span> will be instantiated. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">lets_build</span> <span class="id" type="var">I</span> <span class="id" type="var">Ei</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">args_unfold_head_if_not_product_but_params</span> <span class="id" type="var">args</span> <span class="id" type="keyword">in</span><br/>
<span class="comment">(*&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;Ei'''&nbsp;:=&nbsp;args_unfold_head_if_not_product&nbsp;Ei''&nbsp;in*)</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">R</span> ⇒ <span class="id" type="var">lets_base</span> <span class="id" type="var">I</span> <span class="id" type="var">R</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets_build</span> <span class="id" type="var">I</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> <span class="id" type="keyword">in</span> <span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;--todo:&nbsp;deprecated,&nbsp;do&nbsp;not&nbsp;use&nbsp;*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>]]: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>]]]: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> [<span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>]]]]: <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">forwards</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> is short for
    <span class="inlinecode"><span class="id" type="var">forwards</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> <span class="inlinecode"><span class="id" type="var">___</span>)</span>.
    The arguments <span class="inlinecode"><span class="id" type="var">Ei</span></span> can be wildcards <span class="inlinecode"><span class="id" type="var">__</span></span> (except <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span>).
    <span class="inlinecode"><span class="id" type="var">H</span></span> may be an introduction pattern, or a sequence of
    introduction pattern, or empty.
    Syntax <span class="inlinecode"><span class="id" type="var">forwards</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> is also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">forwards_build_app_arg</span> <span class="id" type="var">Ei</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> (<span class="id" type="var">args</span> ++ ((<span class="id" type="var">boxer</span> <span class="id" type="var">___</span>)::<span class="id" type="var">nil</span>))) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">args_unfold_head_if_not_product</span> <span class="id" type="var">args</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">args</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">forwards_then</span> <span class="id" type="var">Ei</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">forwards_build_app_arg</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">args_unfold_head_if_not_product_but_params</span> <span class="id" type="var">args</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">cont</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">Ei</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">forwards_build_app_arg</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">args</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> <span class="id" type="keyword">in</span> <span class="id" type="var">forwards</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;--TODO:&nbsp;deprecated,&nbsp;do&nbsp;not&nbsp;use&nbsp;*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> [<span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>]: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>]]: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>]]]: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> [<span class="id" type="var">I<sub>1</sub></span> [<span class="id" type="var">I<sub>2</sub></span> [<span class="id" type="var">I<sub>3</sub></span> [<span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>]]]]: <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">forwards_nounfold</span></span> <span class="inlinecode"><span class="id" type="var">I</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is like <span class="inlinecode"><span class="id" type="var">forwards</span></span> <span class="inlinecode"><span class="id" type="var">I</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> but does not
    unfold the head constant of <span class="inlinecode"><span class="id" type="var">E</span></span> if there is no visible quantification
    or hypothesis in <span class="inlinecode"><span class="id" type="var">E</span></span>. It is meant to be used mainly by tactics. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "forwards_nounfold" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">Ei</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> (<span class="id" type="var">args</span> ++ ((<span class="id" type="var">boxer</span> <span class="id" type="var">___</span>)::<span class="id" type="var">nil</span>))) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">R</span> ⇒ <span class="id" type="var">lets_base</span> <span class="id" type="var">I</span> <span class="id" type="var">R</span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">forwards_nounfold_then</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode">..)</span>
    is like <span class="inlinecode"><span class="id" type="var">forwards</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> but it provides the resulting term
    to a continuation, under the name <span class="inlinecode"><span class="id" type="var">K</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">forwards_nounfold_then</span> <span class="id" type="var">Ei</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> (<span class="id" type="var">args</span> ++ ((<span class="id" type="var">boxer</span> <span class="id" type="var">___</span>)::<span class="id" type="var">nil</span>))) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">cont</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">applys</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> instantiates lemma <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span>
    on the arguments <span class="inlinecode"><span class="id" type="var">Ei</span></span> (which may be wildcards <span class="inlinecode"><span class="id" type="var">__</span></span>),
    and apply the resulting term to the current goal,
    using the tactic <span class="inlinecode"><span class="id" type="var">applys</span></span> defined earlier on.
    <span class="inlinecode"><span class="id" type="var">applys</span></span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>2</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> is also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">applys_build</span> <span class="id" type="var">Ei</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">args_unfold_head_if_not_product_but_params</span> <span class="id" type="var">args</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">R</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">apply</span> <span class="id" type="var">R</span> | <span class="id" type="tactic">eapply</span> <span class="id" type="var">R</span> | <span class="id" type="var">rapply</span> <span class="id" type="var">R</span> ]).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">applys_base</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">list</span> <span class="id" type="var">Boxer</span> ⇒ <span class="id" type="var">applys_build</span> <span class="id" type="var">E</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">rapply</span> <span class="id" type="var">E</span> | <span class="id" type="var">applys_build</span> <span class="id" type="var">E</span> ]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>; <span class="id" type="var">fast_rm_inside</span> <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "applys" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_base</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">fapplys</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> instantiates lemma <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span>
    on the arguments <span class="inlinecode"><span class="id" type="var">Ei</span></span> and on the argument <span class="inlinecode"><span class="id" type="var">___</span></span> meaning
    that all evars should be explicitly instantiated,
    and apply the resulting term to the current goal.
    <span class="inlinecode"><span class="id" type="var">fapplys</span></span> <span class="inlinecode"><span class="id" type="var">E<sub>0</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>2</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> is also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">fapplys_build</span> <span class="id" type="var">Ei</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> (<span class="id" type="var">args</span> ++ ((<span class="id" type="var">boxer</span> <span class="id" type="var">___</span>)::<span class="id" type="var">nil</span>))) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">args_unfold_head_if_not_product_but_params</span> <span class="id" type="var">args</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">R</span> ⇒ <span class="id" type="tactic">apply</span> <span class="id" type="var">R</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fapplys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) :=  <span class="comment">(*&nbsp;--todo:&nbsp;use&nbsp;the&nbsp;tactic&nbsp;for&nbsp;that*)</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">list</span> <span class="id" type="var">Boxer</span> ⇒ <span class="id" type="var">fapplys_build</span> <span class="id" type="var">E<sub>0</sub></span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">fapplys_build</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "fapplys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapplys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "fapplys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapplys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "fapplys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapplys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "fapplys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapplys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "fapplys" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapplys</span> (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">specializes</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>2</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> will instantiate hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>
    on the arguments <span class="inlinecode"><span class="id" type="var">Ei</span></span> (which may be wildcards <span class="inlinecode"><span class="id" type="var">__</span></span>). If the last
    argument <span class="inlinecode"><span class="id" type="var">EN</span></span> is <span class="inlinecode"><span class="id" type="var">___</span></span> (triple-underscore), then all arguments of
    <span class="inlinecode"><span class="id" type="var">H</span></span> get instantiated. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">specializes_build</span> <span class="id" type="var">H</span> <span class="id" type="var">Ei</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H'</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">rename</span> <span class="id" type="var">H</span> <span class="id" type="var">into</span> <span class="id" type="var">H'</span>;<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">list_boxer_of</span> <span class="id" type="var">Ei</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">constr</span>:((<span class="id" type="var">boxer</span> <span class="id" type="var">H'</span>)::<span class="id" type="var">args</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">args</span> := <span class="id" type="var">args_unfold_head_if_not_product</span> <span class="id" type="var">args</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">build_app</span> <span class="id" type="var">args</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">R</span> ⇒ <span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">R</span>);<br/>
&nbsp;&nbsp;<span class="id" type="tactic">clear</span> <span class="id" type="var">H'</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">specializes_base</span> <span class="id" type="var">H</span> <span class="id" type="var">Ei</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes_build</span> <span class="id" type="var">H</span> <span class="id" type="var">Ei</span>; <span class="id" type="var">fast_rm_inside</span> <span class="id" type="var">Ei</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes_base</span> <span class="id" type="var">H</span> (<span class="id" type="var">___</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes_base</span> <span class="id" type="var">H</span> <span class="id" type="var">A</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">specializes_vars</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is equivalent to <span class="inlinecode"><span class="id" type="var">specializes</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="var">__</span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">__</span></span>
    with as many double underscore as the number of dependent arguments
    visible from the type of <span class="inlinecode"><span class="id" type="var">H</span></span>. Note that no unfolding is currently
    being performed (this behavior might change in the future).
    The current implementation is restricted to the case where
    <span class="inlinecode"><span class="id" type="var">H</span></span> is an existing hypothesis &mdash; TODO: generalize. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">specializes_var_base</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>:_, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">__</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">specializes_vars_base</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> (<span class="id" type="var">specializes_var_base</span> <span class="id" type="var">H</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "specializes_var" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes_var_base</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "specializes_vars" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes_vars_base</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<a name="lab477"></a><h2 class="section">Experimental Tactics for Application</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">fapply</span></span> is a version of <span class="inlinecode"><span class="id" type="tactic">apply</span></span> based on <span class="inlinecode"><span class="id" type="var">forwards</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "fapply" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">forwards</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span> | <span class="id" type="tactic">eapply</span> <span class="id" type="var">H</span> | <span class="id" type="var">rapply</span> <span class="id" type="var">H</span> | <span class="id" type="var">hnf</span>; <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">hnf</span>; <span class="id" type="tactic">eapply</span> <span class="id" type="var">H</span> | <span class="id" type="var">applys</span> <span class="id" type="var">H</span> ].<br/>
&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;is&nbsp;applys&nbsp;redundant&nbsp;with&nbsp;rapply&nbsp;?&nbsp;*)</span><br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">sapply</span></span> stands for "super apply". It tries
    <span class="inlinecode"><span class="id" type="tactic">apply</span></span>, <span class="inlinecode"><span class="id" type="tactic">eapply</span></span>, <span class="inlinecode"><span class="id" type="var">applys</span></span> and <span class="inlinecode"><span class="id" type="var">fapply</span></span>,
    and also tries to head-normalize the goal first. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "sapply" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span> | <span class="id" type="tactic">eapply</span> <span class="id" type="var">H</span> | <span class="id" type="var">rapply</span> <span class="id" type="var">H</span> | <span class="id" type="var">applys</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">hnf</span>; <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span> | <span class="id" type="var">hnf</span>; <span class="id" type="tactic">eapply</span> <span class="id" type="var">H</span> | <span class="id" type="var">hnf</span>; <span class="id" type="var">applys</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">fapply</span> <span class="id" type="var">H</span> ].<br/>
</div>

<div class="doc">
<a name="lab478"></a><h2 class="section">Adding Assumptions</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">lets_simpl</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is the same as <span class="inlinecode"><span class="id" type="var">lets</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> excepts that it
    calls <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> on the hypothesis H.
    <span class="inlinecode"><span class="id" type="var">lets_simpl</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is also provided. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "lets_simpl" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; <span class="id" type="tactic">try</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets_simpl" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">lets_simpl</span> <span class="id" type="var">H</span>: <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">lets_hnf</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is the same as <span class="inlinecode"><span class="id" type="var">lets</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> excepts that it
    calls <span class="inlinecode"><span class="id" type="var">hnf</span></span> to set the definition in head normal form.
    <span class="inlinecode"><span class="id" type="var">lets_hnf</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is also provided. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "lets_hnf" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets_hnf" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">lets_hnf</span> <span class="id" type="var">H</span>: <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">puts</span></span> <span class="inlinecode"><span class="id" type="var">X</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a synonymous for <span class="inlinecode"><span class="id" type="var">pose</span></span> <span class="inlinecode">(<span class="id" type="var">X</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">E</span>)</span>.
    Alternative syntax is <span class="inlinecode"><span class="id" type="var">puts</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "puts" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pose</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "puts" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">pose</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>).<br/>
</div>

<div class="doc">
<a name="lab479"></a><h2 class="section">Application of Tautologies</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">logic</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span>, where <span class="inlinecode"><span class="id" type="var">E</span></span> is a fact, is equivalent to
    <span class="inlinecode"><span class="id" type="tactic">assert</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:<span class="id" type="var">E</span>;</span> <span class="inlinecode">[<span class="id" type="tactic">tauto</span></span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="tactic">eapply</span></span> <span class="inlinecode"><span class="id" type="var">H</span>;</span> <span class="inlinecode"><span class="id" type="tactic">clear</span></span> <span class="inlinecode"><span class="id" type="var">H</span>].</span> <span class="inlinecode"><span class="id" type="var">It</span></span> <span class="inlinecode"><span class="id" type="var">is</span></span> <span class="inlinecode"><span class="id" type="var">useful</span></span> <span class="inlinecode"><span class="id" type="keyword">for</span></span> <span class="inlinecode"><span class="id" type="var">instance</span></span>
    <span class="inlinecode"><span class="id" type="var">to</span></span> <span class="inlinecode"><span class="id" type="var">prove</span></span> <span class="inlinecode"><span class="id" type="var">a</span></span> <span class="inlinecode"><span class="id" type="var">conjunction</span></span> <span class="inlinecode">[<span class="id" type="var">A</span></span> <span class="inlinecode">∧</span> <span class="inlinecode"><span class="id" type="var">B</span>]</span> <span class="inlinecode"><span class="id" type="tactic">by</span></span> <span class="inlinecode"><span class="id" type="var">showing</span></span> <span class="inlinecode"><span class="id" type="var">first</span></span> <span class="inlinecode">[<span class="id" type="var">A</span>]</span> <span class="inlinecode"><span class="id" type="var">and</span></span> <span class="inlinecode"><span class="id" type="keyword">then</span></span> <span class="inlinecode">[<span class="id" type="var">A</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">B</span>],</span>
    <span class="inlinecode"><span class="id" type="var">through</span></span> <span class="inlinecode"><span class="id" type="var">the</span></span> <span class="inlinecode"><span class="id" type="var">command</span></span> <span class="inlinecode">[<span class="id" type="var">logic</span></span> <span class="inlinecode">(<span class="id" type="var">foral</span></span> <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode"><span class="id" type="var">B</span>,</span> <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode">→</span> <span class="inlinecode">(<span class="id" type="var">A</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">B</span>)</span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode">∧</span> <span class="inlinecode"><span class="id" type="var">B</span>)]</span> <span class="inlinecode"></span>
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">logic_base</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">H</span>:<span class="id" type="var">E</span>); [ <span class="id" type="var">cont</span> <span class="id" type="var">tt</span> | <span class="id" type="tactic">eapply</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "logic" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">logic_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">tauto</span>).<br/>
</div>

<div class="doc">
<a name="lab480"></a><h2 class="section">Application Modulo Equalities</h2>

<div class="paragraph"> </div>

 The tactic <span class="inlinecode"><span class="id" type="var">equates</span></span> replaces a goal of the form
    <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode"><span class="id" type="var">y</span></span> <span class="inlinecode"><span class="id" type="var">z</span></span> with a goal of the form <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">?<span class="id" type="var">a</span></span> <span class="inlinecode"><span class="id" type="var">z</span></span> and a
    subgoal <span class="inlinecode">?<span class="id" type="var">a</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">y</span></span>. The introduction of the evar <span class="inlinecode">?<span class="id" type="var">a</span></span> makes
    it possible to apply lemmas that would not apply to the
    original goal, for example a lemma of the form
    <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span> <span class="inlinecode"><span class="id" type="var">m</span>,</span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span> <span class="inlinecode"><span class="id" type="var">n</span></span> <span class="inlinecode"><span class="id" type="var">m</span></span>, because <span class="inlinecode"><span class="id" type="var">x</span></span> and <span class="inlinecode"><span class="id" type="var">y</span></span> might be equal
    but not convertible.

<div class="paragraph"> </div>

    Usage is <span class="inlinecode"><span class="id" type="var">equates</span></span> <span class="inlinecode"><span class="id" type="var">i<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">ik</span></span>, where the indices are the
    positions of the arguments to be replaced by evars,
    counting from the right-hand side. If <span class="inlinecode">0</span> is given as
    argument, then the entire goal is replaced by an evar. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Section</span> <span class="id" type="var">equatesLemma</span>.<br/>
<span class="id" type="keyword">Variables</span> (<span class="id" type="var">A<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> : <span class="id" type="keyword">Type</span>).<br/>
<span class="id" type="keyword">Variables</span> (<span class="id" type="var">A<sub>2</sub></span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span> : <span class="id" type="var">A<sub>1</sub></span>), <span class="id" type="keyword">Type</span>).<br/>
<span class="id" type="keyword">Variables</span> (<span class="id" type="var">A<sub>3</sub></span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span> : <span class="id" type="var">A<sub>1</sub></span>) (<span class="id" type="var">x<sub>2</sub></span> : <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>), <span class="id" type="keyword">Type</span>).<br/>
<span class="id" type="keyword">Variables</span> (<span class="id" type="var">A<sub>4</sub></span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span> : <span class="id" type="var">A<sub>1</sub></span>) (<span class="id" type="var">x<sub>2</sub></span> : <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>) (<span class="id" type="var">x<sub>3</sub></span> : <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">x<sub>2</sub></span>), <span class="id" type="keyword">Type</span>).<br/>
<span class="id" type="keyword">Variables</span> (<span class="id" type="var">A<sub>5</sub></span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span> : <span class="id" type="var">A<sub>1</sub></span>) (<span class="id" type="var">x<sub>2</sub></span> : <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>) (<span class="id" type="var">x<sub>3</sub></span> : <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">x<sub>2</sub></span>) (<span class="id" type="var">x<sub>4</sub></span> : <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">x<sub>3</sub></span>), <span class="id" type="keyword">Type</span>).<br/>
<span class="id" type="keyword">Variables</span> (<span class="id" type="var">A<sub>6</sub></span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span> : <span class="id" type="var">A<sub>1</sub></span>) (<span class="id" type="var">x<sub>2</sub></span> : <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>) (<span class="id" type="var">x<sub>3</sub></span> : <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">x<sub>2</sub></span>) (<span class="id" type="var">x<sub>4</sub></span> : <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">x<sub>3</sub></span>) (<span class="id" type="var">x<sub>5</sub></span> : <span class="id" type="var">A<sub>5</sub></span> <span class="id" type="var">x<sub>4</sub></span>), <span class="id" type="keyword">Type</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_0</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">P</span> <span class="id" type="var">Q</span>:<span class="id" type="keyword">Prop</span>),<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> → <span class="id" type="var">P</span> = <span class="id" type="var">Q</span> → <span class="id" type="var">Q</span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_1</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">P</span>:<span class="id" type="var">A<sub>0</sub></span>→<span class="id" type="keyword">Prop</span>) <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">y<sub>1</sub></span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">x<sub>1</sub></span> = <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">P</span> <span class="id" type="var">x<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_2</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">y<sub>1</sub></span> (<span class="id" type="var">P</span>:<span class="id" type="var">A<sub>0</sub></span>→<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span>:<span class="id" type="var">A<sub>1</sub></span>),<span class="id" type="keyword">Prop</span>) <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> → <span class="id" type="var">x<sub>1</sub></span> = <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">P</span> <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_3</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">y<sub>1</sub></span> (<span class="id" type="var">P</span>:<span class="id" type="var">A<sub>0</sub></span>→<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span>:<span class="id" type="var">A<sub>1</sub></span>)(<span class="id" type="var">x<sub>2</sub></span>:<span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>),<span class="id" type="keyword">Prop</span>) <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> → <span class="id" type="var">x<sub>1</sub></span> = <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">P</span> <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_4</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">y<sub>1</sub></span> (<span class="id" type="var">P</span>:<span class="id" type="var">A<sub>0</sub></span>→<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span>:<span class="id" type="var">A<sub>1</sub></span>)(<span class="id" type="var">x<sub>2</sub></span>:<span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>)(<span class="id" type="var">x<sub>3</sub></span>:<span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">x<sub>2</sub></span>),<span class="id" type="keyword">Prop</span>) <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> → <span class="id" type="var">x<sub>1</sub></span> = <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">P</span> <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_5</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">y<sub>1</sub></span> (<span class="id" type="var">P</span>:<span class="id" type="var">A<sub>0</sub></span>→<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span>:<span class="id" type="var">A<sub>1</sub></span>)(<span class="id" type="var">x<sub>2</sub></span>:<span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>)(<span class="id" type="var">x<sub>3</sub></span>:<span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">x<sub>2</sub></span>)(<span class="id" type="var">x<sub>4</sub></span>:<span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">x<sub>3</sub></span>),<span class="id" type="keyword">Prop</span>) <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> → <span class="id" type="var">x<sub>1</sub></span> = <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">P</span> <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">equates_6</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">y<sub>1</sub></span> (<span class="id" type="var">P</span>:<span class="id" type="var">A<sub>0</sub></span>→<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">x<sub>1</sub></span>:<span class="id" type="var">A<sub>1</sub></span>)(<span class="id" type="var">x<sub>2</sub></span>:<span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">x<sub>1</sub></span>)(<span class="id" type="var">x<sub>3</sub></span>:<span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">x<sub>2</sub></span>)(<span class="id" type="var">x<sub>4</sub></span>:<span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">x<sub>3</sub></span>)(<span class="id" type="var">x<sub>5</sub></span>:<span class="id" type="var">A<sub>5</sub></span> <span class="id" type="var">x<sub>4</sub></span>),<span class="id" type="keyword">Prop</span>)<br/>
&nbsp;&nbsp;<span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> <span class="id" type="var">x<sub>6</sub></span>,<br/>
&nbsp;&nbsp;<span class="id" type="var">P</span> <span class="id" type="var">y<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> <span class="id" type="var">x<sub>6</sub></span> → <span class="id" type="var">x<sub>1</sub></span> = <span class="id" type="var">y<sub>1</sub></span> → <span class="id" type="var">P</span> <span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> <span class="id" type="var">x<sub>6</sub></span>.<br/>
<span class="id" type="keyword">Proof</span>. <span class="id" type="tactic">intros</span>. <span class="id" type="tactic">subst</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">End</span> <span class="id" type="var">equatesLemma</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">equates_lemma</span> <span class="id" type="var">n</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">n</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 0 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_0</span>)<br/>
&nbsp;&nbsp;| 1 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_1</span>)<br/>
&nbsp;&nbsp;| 2 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_2</span>)<br/>
&nbsp;&nbsp;| 3 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_3</span>)<br/>
&nbsp;&nbsp;| 4 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_4</span>)<br/>
&nbsp;&nbsp;| 5 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_5</span>)<br/>
&nbsp;&nbsp;| 6 ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">equates_6</span>)<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">equates_one</span> <span class="id" type="var">n</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">L</span> := <span class="id" type="var">equates_lemma</span> <span class="id" type="var">n</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">eapply</span> <span class="id" type="var">L</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">equates_several</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">all_pos</span> := <span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">List.list</span> <span class="id" type="var">Boxer</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">E</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:((<span class="id" type="var">boxer</span> <span class="id" type="var">E</span>)::<span class="id" type="var">nil</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">pos</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">pos</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">nil</span> ⇒ <span class="id" type="var">cont</span> <span class="id" type="var">tt</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| (<span class="id" type="var">boxer</span> ?<span class="id" type="var">n</span>)::?<span class="id" type="var">pos'</span> ⇒ <span class="id" type="var">equates_one</span> <span class="id" type="var">n</span>; [ <span class="id" type="var">instantiate</span>; <span class="id" type="var">go</span> <span class="id" type="var">pos'</span> | ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">all_pos</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "equates" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates_several</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> (&gt;&gt; <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> (&gt;&gt; <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> (&gt;&gt; <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span> <span class="id" type="var">n<sub>4</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">applys_eq</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="var">i<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">iK</span></span> is the same as
    <span class="inlinecode"><span class="id" type="var">equates</span></span> <span class="inlinecode"><span class="id" type="var">i<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">iK</span></span> followed by <span class="inlinecode"><span class="id" type="tactic">apply</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    on the first subgoal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "applys_eq" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates_several</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">sapply</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> (&gt;&gt; <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span> <span class="id" type="var">n<sub>4</sub></span>).<br/>
</div>

<div class="doc">
<a name="lab481"></a><h2 class="section">Absurd Goals</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">false_goal</span></span> replaces any goal by the goal <span class="inlinecode"><span class="id" type="var">False</span></span>.
    Contrary to the tactic <span class="inlinecode"><span class="id" type="var">false</span></span> (below), it does not try to do
    anything else 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "false_goal" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">elimtype</span> <span class="id" type="var">False</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">false_post</span></span> is the underlying tactic used to prove goals
    of the form <span class="inlinecode"><span class="id" type="var">False</span></span>. In the default implementation, it proves
    the goal if the context contains <span class="inlinecode"><span class="id" type="var">False</span></span> or an hypothesis of the
    form <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">x<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">xN</span></span>  <span class="inlinecode">=</span>  <span class="inlinecode"><span class="id" type="var">D</span></span> <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">yM</span></span>, or if the <span class="inlinecode"><span class="id" type="tactic">congruence</span></span> tactic
    finds a proof of <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">≠</span> <span class="inlinecode"><span class="id" type="var">x</span></span> for some <span class="inlinecode"><span class="id" type="var">x</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">false_post</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">solve</span> [ <span class="id" type="tactic">assumption</span> | <span class="id" type="tactic">discriminate</span> | <span class="id" type="tactic">congruence</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">false</span></span> replaces any goal by the goal <span class="inlinecode"><span class="id" type="var">False</span></span>, and calls <span class="inlinecode"><span class="id" type="var">false_post</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "false" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false_goal</span>; <span class="id" type="tactic">try</span> <span class="id" type="var">false_post</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">tryfalse</span></span> tries to solve a goal by contradiction, and leaves
    the goal unchanged if it cannot solve it.
    It is equivalent to <span class="inlinecode"><span class="id" type="tactic">try</span></span> <span class="inlinecode"><span class="id" type="var">solve</span></span> <span class="inlinecode">\[</span> <span class="inlinecode"><span class="id" type="var">false</span></span> <span class="inlinecode">\]</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "tryfalse" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="var">false</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">false</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> tries to exploit lemma <span class="inlinecode"><span class="id" type="var">E</span></span> to prove the goal false.
    <span class="inlinecode"><span class="id" type="var">false</span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span></span> is equivalent to <span class="inlinecode"><span class="id" type="var">false</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span>,
    which tries to apply <span class="inlinecode"><span class="id" type="var">applys</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span> and if it
    does not work then tries <span class="inlinecode"><span class="id" type="var">forwards</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">EN</span>)</span>
    followed with <span class="inlinecode"><span class="id" type="var">false</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">false_then</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false_goal</span>; <span class="id" type="var">first</span><br/>
&nbsp;&nbsp;[ <span class="id" type="var">applys</span> <span class="id" type="var">E</span>; <span class="id" type="var">instantiate</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">forwards_then</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">pose</span> <span class="id" type="var">M</span>; <span class="id" type="var">jauto_set_hyps</span>; <span class="id" type="tactic">intros</span>; <span class="id" type="var">false</span>) ];<br/>
&nbsp;&nbsp;<span class="id" type="var">cont</span> <span class="id" type="var">tt</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;is&nbsp;<span class="inlinecode"><span class="id" type="var">cont</span></span>&nbsp;needed?&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "false" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false_then</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span> (&gt;&gt; <span class="id" type="var">E</span> <span class="id" type="var">E<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span> (&gt;&gt; <span class="id" type="var">E</span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span> (&gt;&gt; <span class="id" type="var">E</span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span> <span class="id" type="var">E<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span> (&gt;&gt; <span class="id" type="var">E</span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span> <span class="id" type="var">E<sub>3</sub></span> <span class="id" type="var">E<sub>4</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">false_invert</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> proves a goal if it absurd after
    calling <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> and <span class="inlinecode"><span class="id" type="var">false</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">false_invert_for</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">M</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">pose</span> (<span class="id" type="var">M</span> := <span class="id" type="var">H</span>); <span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="var">false</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "false_invert" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="var">false_invert_for</span> <span class="id" type="var">H</span> | <span class="id" type="var">false</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">false_invert</span></span> proves any goal provided there is at least
    one hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span> in the context (or as a universally quantified
    hypothesis visible at the head of the goal) that can be proved absurd by calling
    <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">false_invert_iter</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>:_ &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">solve</span> [ <span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="var">false</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="var">false_invert_iter</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 2 ] <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "false_invert" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span>; <span class="id" type="var">solve</span> [ <span class="id" type="var">false_invert_iter</span> | <span class="id" type="var">false</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">tryfalse_invert</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> and <span class="inlinecode"><span class="id" type="var">tryfalse_invert</span></span> are like the
    above but leave the goal unchanged if they don't solve it. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "tryfalse_invert" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> (<span class="id" type="var">false_invert</span> <span class="id" type="var">H</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "tryfalse_invert" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">false_invert</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">false_neq_self_hyp</span></span> proves any goal if the context
    contains an hypothesis of the form <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode">≠</span> <span class="inlinecode"><span class="id" type="var">E</span></span>. It is
    a restricted and optimized version of <span class="inlinecode"><span class="id" type="var">false</span></span>. It is
    intended to be used by other tactics only. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">false_neq_self_hyp</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">x</span> ≠ ?<span class="id" type="var">x</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">false_goal</span>; <span class="id" type="tactic">apply</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">reflexivity</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab482"></a><h1 class="section">Introduction and Generalization</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab483"></a><h2 class="section">Introduction</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">introv</span></span> is used to name only non-dependent hypothesis.

<div class="paragraph"> </div>

<ul class="doclist">
<li> If <span class="inlinecode"><span class="id" type="var">introv</span></span> is called on a goal of the form <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">x</span>,</span> <span class="inlinecode"><span class="id" type="var">H</span></span>,
   it should introduce all the variables quantified with a
   <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> at the head of the goal, but it does not introduce
   hypotheses that preceed an arrow constructor, like in <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">Q</span></span>.

</li>
<li> If <span class="inlinecode"><span class="id" type="var">introv</span></span> is called on a goal that is not of the form
   <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">x</span>,</span> <span class="inlinecode"><span class="id" type="var">H</span></span> nor <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">Q</span></span>, the tactic unfolds definitions
   until the goal takes the form <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">x</span>,</span> <span class="inlinecode"><span class="id" type="var">H</span></span> or <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">Q</span></span>.
   If unfolding definitions does not produces a goal of this form,
   then the tactic <span class="inlinecode"><span class="id" type="var">introv</span></span> does nothing at all. 
</li>
</ul>

</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;<span class="inlinecode"><span class="id" type="var">introv_rec</span></span>&nbsp;introduces&nbsp;all&nbsp;visible&nbsp;variables.<br/>
&nbsp;&nbsp;&nbsp;It&nbsp;does&nbsp;not&nbsp;try&nbsp;to&nbsp;unfold&nbsp;any&nbsp;definition.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">introv_rec</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| &#x22A2; <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">intro</span>; <span class="id" type="var">introv_rec</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;<span class="inlinecode"><span class="id" type="var">introv_noarg</span></span>&nbsp;forces&nbsp;the&nbsp;goal&nbsp;to&nbsp;be&nbsp;a&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span>&nbsp;or&nbsp;an&nbsp;<span class="inlinecode">→</span>,<br/>
&nbsp;&nbsp;&nbsp;and&nbsp;then&nbsp;calls&nbsp;<span class="inlinecode"><span class="id" type="var">introv_rec</span></span>&nbsp;to&nbsp;introduces&nbsp;variables<br/>
&nbsp;&nbsp;&nbsp;(possibly&nbsp;none,&nbsp;in&nbsp;which&nbsp;case&nbsp;<span class="inlinecode"><span class="id" type="var">introv</span></span>&nbsp;is&nbsp;the&nbsp;same&nbsp;as&nbsp;<span class="inlinecode"><span class="id" type="var">hnf</span></span>).<br/>
&nbsp;&nbsp;&nbsp;If&nbsp;the&nbsp;goal&nbsp;is&nbsp;not&nbsp;a&nbsp;product,&nbsp;then&nbsp;it&nbsp;does&nbsp;not&nbsp;do&nbsp;anything.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">introv_noarg</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| &#x22A2; <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">introv_rec</span><br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">G</span> ⇒ <span class="id" type="var">hnf</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">introv_rec</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;simpler&nbsp;yet&nbsp;perhaps&nbsp;less&nbsp;efficient&nbsp;imlementation&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">Ltac</span> <span class="id" type="var">introv_noarg_not_optimized</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">intro</span>; <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>:_&#x22A2;_ ⇒ <span class="id" type="var">revert</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>; <span class="id" type="var">introv_rec</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;<span class="inlinecode"><span class="id" type="var">introv_arg</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>&nbsp;introduces&nbsp;one&nbsp;non-dependent&nbsp;hypothesis<br/>
&nbsp;&nbsp;&nbsp;under&nbsp;the&nbsp;name&nbsp;<span class="inlinecode"><span class="id" type="var">H</span></span>,&nbsp;after&nbsp;introducing&nbsp;the&nbsp;variables<br/>
&nbsp;&nbsp;&nbsp;quantified&nbsp;with&nbsp;a&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span>&nbsp;that&nbsp;preceeds&nbsp;this&nbsp;hypothesis.<br/>
&nbsp;&nbsp;&nbsp;This&nbsp;tactic&nbsp;fails&nbsp;if&nbsp;there&nbsp;does&nbsp;not&nbsp;exist&nbsp;a&nbsp;hypothesis<br/>
&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;introduced.&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;todo:&nbsp;__&nbsp;in&nbsp;introv&nbsp;means&nbsp;"intros"&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">introv_arg</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hnf</span>; <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span> ⇒ <span class="id" type="tactic">intros</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| &#x22A2; <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">intro</span>; <span class="id" type="var">introv_arg</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;<span class="inlinecode"><span class="id" type="var">introv</span></span> <span class="inlinecode"><span class="id" type="var">I<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">IN</span></span>&nbsp;iterates&nbsp;<span class="inlinecode"><span class="id" type="var">introv</span></span> <span class="inlinecode"><span class="id" type="var">Ik</span></span>&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "introv" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv_noarg</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv_arg</span> <span class="id" type="var">I<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>9</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span> <span class="id" type="var">I<sub>9</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "introv" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>9</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>10</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span> <span class="id" type="var">I<sub>9</sub></span> <span class="id" type="var">I<sub>10</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">intros_all</span></span> repeats <span class="inlinecode"><span class="id" type="tactic">intro</span></span> as long as possible. Contrary to <span class="inlinecode"><span class="id" type="tactic">intros</span></span>,
    it unfolds any definition on the way. Remark that it also unfolds the
    definition of negation, so applying <span class="inlinecode"><span class="id" type="var">intros_all</span></span> to a goal of the form
    <span class="inlinecode"><span style='font-size:120%;'>&forall;</span></span> <span class="inlinecode"><span class="id" type="var">x</span>,</span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">→</span> <span class="inlinecode">¬<span class="id" type="var">Q</span></span> will introduce <span class="inlinecode"><span class="id" type="var">x</span></span> and <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> and <span class="inlinecode"><span class="id" type="var">Q</span></span>, and will
    leave <span class="inlinecode"><span class="id" type="var">False</span></span> in the goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "intros_all" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">intro</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">intros_hnf</span></span> introduces an hypothesis and sets in head normal form 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "intro_hnf" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intro</span>; <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab484"></a><h2 class="section">Introduction using <span class="inlinecode">⇒</span> and <span class="inlinecode">=&gt;&gt;</span></h2>

</div>
<div class="code code-space">

<br/>
<span class="comment">(*&nbsp;<span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">I<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">IN</span></span>&nbsp;is&nbsp;the&nbsp;same&nbsp;as&nbsp;<span class="inlinecode"><span class="id" type="tactic">intros</span></span> <span class="inlinecode"><span class="id" type="var">I<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">IN</span></span>&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">ltac_intros_post</span> := <span class="id" type="var">idtac</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>9</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span> <span class="id" type="var">I<sub>9</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "⇒" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>9</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>10</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span> <span class="id" type="var">I<sub>9</sub></span> <span class="id" type="var">I<sub>10</sub></span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;<span class="inlinecode">=&gt;&gt;</span>&nbsp;first&nbsp;introduces&nbsp;all&nbsp;non-dependent&nbsp;variables,<br/>
&nbsp;&nbsp;&nbsp;then&nbsp;behaves&nbsp;as&nbsp;<span class="inlinecode"><span class="id" type="tactic">intros</span></span>.&nbsp;It&nbsp;unfolds&nbsp;the&nbsp;head&nbsp;of&nbsp;the&nbsp;goal&nbsp;using&nbsp;<span class="inlinecode"><span class="id" type="var">hnf</span></span><br/>
&nbsp;&nbsp;&nbsp;if&nbsp;there&nbsp;are&nbsp;not&nbsp;head&nbsp;visible&nbsp;quantifiers.<br/>
<br/>
&nbsp;&nbsp;&nbsp;Remark:&nbsp;instances&nbsp;of&nbsp;<span class="inlinecode"><span class="id" type="var">Inhab</span></span>&nbsp;are&nbsp;treated&nbsp;as&nbsp;non-dependent&nbsp;and<br/>
&nbsp;&nbsp;&nbsp;are&nbsp;introduced&nbsp;automatically.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;NOTE:&nbsp;this&nbsp;tactic&nbsp;is&nbsp;later&nbsp;redefined&nbsp;for&nbsp;supporting&nbsp;Inhab&nbsp;*)</span><br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">intro_nondeps_aux_special_intro</span> <span class="id" type="var">G</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">fail</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">intro_nondeps_aux</span> <span class="id" type="var">is_already_hnf</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; (?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span>) ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">G</span> → <span class="id" type="var">_</span> ⇒ <span class="id" type="var">intro_nondeps_aux_special_intro</span> <span class="id" type="var">G</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">intro</span>; <span class="id" type="var">intro_nondeps_aux</span> <span class="id" type="var">true</span><br/>
&nbsp;&nbsp;| &#x22A2; (<span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>,_) ⇒ <span class="id" type="tactic">intros</span> ?; <span class="id" type="var">intro_nondeps_aux</span> <span class="id" type="var">true</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">is_already_hnf</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">true</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">false</span> ⇒ <span class="id" type="var">hnf</span>; <span class="id" type="var">intro_nondeps_aux</span> <span class="id" type="var">true</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">intro_nondeps</span> <span class="id" type="var">tt</span> := <span class="id" type="var">intro_nondeps_aux</span> <span class="id" type="var">false</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">intro_nondeps</span> <span class="id" type="var">tt</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>9</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span> <span class="id" type="var">I<sub>9</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "=&gt;&gt;" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>9</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>10</sub></span>) :=<br/>
&nbsp;&nbsp;=&gt;&gt;; <span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span> <span class="id" type="var">I<sub>9</sub></span> <span class="id" type="var">I<sub>10</sub></span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;----------------------------------------------------------------------&nbsp;*)</span><br/>
</div>

<div class="doc">
<a name="lab485"></a><h2 class="section">Generalization</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">gen</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is a shorthand for calling <span class="inlinecode"><span class="id" type="tactic">generalize</span></span> <span class="inlinecode"><span class="id" type="tactic">dependent</span></span>
    successively on variables <span class="inlinecode"><span class="id" type="var">XN</span></span>...<span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span>. Note that the variables
    are generalized in reverse order, following the convention of
    the <span class="inlinecode"><span class="id" type="tactic">generalize</span></span> tactic: it means that <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> will be the first
    quantified variable in the resulting goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="tactic">dependent</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>)  :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>7</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>8</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>7</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>8</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>9</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>9</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>8</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>7</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>8</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>9</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>10</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen</span> <span class="id" type="var">X<sub>10</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>9</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>8</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">gen</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">generalizes</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> is a shorthand for calling <span class="inlinecode"><span class="id" type="tactic">generalize</span></span> <span class="inlinecode"><span class="id" type="var">X</span>;</span> <span class="inlinecode"><span class="id" type="tactic">clear</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span>.
    It is weaker than tactic <span class="inlinecode"><span class="id" type="var">gen</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> since it does not support
    dependencies. It is mainly intended for writing tactics. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "generalizes" <span class="id" type="var">hyp</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">X</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">X</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "generalizes" <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">generalizes</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">generalizes</span> <span class="id" type="var">X<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "generalizes" <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">generalizes</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">generalizes</span> <span class="id" type="var">X<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "generalizes" <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">X<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">generalizes</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">generalizes</span> <span class="id" type="var">X<sub>4</sub></span>.<br/>
</div>

<div class="doc">
<a name="lab486"></a><h2 class="section">Naming</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">sets</span></span> <span class="inlinecode"><span class="id" type="var">X</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">set</span></span> <span class="inlinecode">(<span class="id" type="var">X</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">E</span>)</span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*</span>, that is,
    it replaces all occurences of <span class="inlinecode"><span class="id" type="var">E</span></span> by a fresh meta-variable <span class="inlinecode"><span class="id" type="var">X</span></span>
    whose definition is <span class="inlinecode"><span class="id" type="var">E</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "sets" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">def_to_eq</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> applies when <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode">:=</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a local
    definition. It adds an assumption <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">E</span></span>
    and then clears the definition of <span class="inlinecode"><span class="id" type="var">X</span></span>.
    <span class="inlinecode"><span class="id" type="var">def_to_eq_sym</span></span> is similar except that it generates
    the equality <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">X</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">def_to_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">HX</span> : <span class="id" type="var">X</span> = <span class="id" type="var">E</span>) <span class="id" type="tactic">by</span> <span class="id" type="tactic">reflexivity</span>; <span class="id" type="var">clearbody</span> <span class="id" type="var">X</span>.<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">def_to_eq_sym</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">assert</span> (<span class="id" type="var">HX</span> : <span class="id" type="var">E</span> = <span class="id" type="var">X</span>) <span class="id" type="tactic">by</span> <span class="id" type="tactic">reflexivity</span>; <span class="id" type="var">clearbody</span> <span class="id" type="var">X</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">set_eq</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> generates the equality <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">E</span></span>,
    for a fresh name <span class="inlinecode"><span class="id" type="var">X</span></span>, and replaces <span class="inlinecode"><span class="id" type="var">E</span></span> by <span class="inlinecode"><span class="id" type="var">X</span></span> in the
    current goal. Syntaxes <span class="inlinecode"><span class="id" type="var">set_eq</span></span> <span class="inlinecode"><span class="id" type="var">X</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> and
    <span class="inlinecode"><span class="id" type="var">set_eq</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> are also available. Similarly,
    <span class="inlinecode"><span class="id" type="var">set_eq</span></span> <span class="inlinecode">&lt;-</span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> generates the equality <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">X</span></span>.

<div class="paragraph"> </div>

    <span class="inlinecode"><span class="id" type="var">sets_eq</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="var">HX</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> does the same but replaces <span class="inlinecode"><span class="id" type="var">E</span></span> by <span class="inlinecode"><span class="id" type="var">X</span></span>
    everywhere in the goal. <span class="inlinecode"><span class="id" type="var">sets_eq</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="var">HX</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> replaces in <span class="inlinecode"><span class="id" type="var">H</span></span>.
    <span class="inlinecode"><span class="id" type="var">set_eq</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="var">HX</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">&#x22A2;</span> performs no substitution at all. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "set_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>); <span class="id" type="var">def_to_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>); <span class="id" type="var">def_to_eq_sym</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> &lt;- <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> &lt;- <span class="id" type="var">X</span>: <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> *; <span class="id" type="var">def_to_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">sets_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">sets_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> *; <span class="id" type="var">def_to_eq_sym</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">sets_eq</span> &lt;- <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq" "&lt;-" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">sets_eq</span> &lt;- <span class="id" type="var">X</span>: <span class="id" type="var">E</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">def_to_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">def_to_eq_sym</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> &lt;- <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> &lt;- <span class="id" type="var">X</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "&#x22A2;" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> &#x22A2;; <span class="id" type="var">def_to_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "&#x22A2;" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> &#x22A2;.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "&#x22A2;" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> &#x22A2;.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">HX</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "&#x22A2;" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> &#x22A2;; <span class="id" type="var">def_to_eq_sym</span> <span class="id" type="var">X</span> <span class="id" type="var">HX</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "&#x22A2;" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">HX</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> &lt;- <span class="id" type="var">X</span> <span class="id" type="var">HX</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> &#x22A2;.<br/>
<span class="id" type="keyword">Tactic Notation</span> "set_eq" "&lt;-" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "&#x22A2;" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">set_eq</span> &lt;- <span class="id" type="var">X</span>: <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> &#x22A2;.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">gen_eq</span></span> <span class="inlinecode"><span class="id" type="var">X</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a tactic whose purpose is to introduce
    equalities so as to work around the limitation of the <span class="inlinecode"><span class="id" type="tactic">induction</span></span>
    tactic which typically loses information. <span class="inlinecode"><span class="id" type="var">gen_eq</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> replaces
    all occurences of term <span class="inlinecode"><span class="id" type="var">E</span></span> with a fresh variable <span class="inlinecode"><span class="id" type="var">X</span></span> and the equality
    <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">E</span></span> as extra hypothesis to the current conclusion. In other words
    a conclusion <span class="inlinecode"><span class="id" type="var">C</span></span> will be turned into <span class="inlinecode">(<span class="id" type="var">X</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">E</span>)</span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">C</span></span>.
    <span class="inlinecode"><span class="id" type="var">gen_eq</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> and <span class="inlinecode"><span class="id" type="var">gen_eq</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> are also accepted. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "gen_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">EQ</span> := <span class="id" type="tactic">fresh</span> "EQ" <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">sets_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">EQ</span>: <span class="id" type="var">E</span>; <span class="id" type="var">revert</span> <span class="id" type="var">EQ</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen_eq" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "X" <span class="id" type="keyword">in</span> <span class="id" type="var">gen_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen_eq" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) ","<br/>
&nbsp;&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen_eq</span> <span class="id" type="var">X<sub>2</sub></span>: <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">gen_eq</span> <span class="id" type="var">X<sub>1</sub></span>: <span class="id" type="var">E<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "gen_eq" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) ","<br/>
&nbsp;&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">gen_eq</span> <span class="id" type="var">X<sub>3</sub></span>: <span class="id" type="var">E<sub>3</sub></span>; <span class="id" type="var">gen_eq</span> <span class="id" type="var">X<sub>2</sub></span>: <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">gen_eq</span> <span class="id" type="var">X<sub>1</sub></span>: <span class="id" type="var">E<sub>1</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">sets_let</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> finds the first let-expression in the goal
    and names its body <span class="inlinecode"><span class="id" type="var">X</span></span>. <span class="inlinecode"><span class="id" type="var">sets_eq_let</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> is similar,
    except that it generates an explicit equality.
    Tactics <span class="inlinecode"><span class="id" type="var">sets_let</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> and <span class="inlinecode"><span class="id" type="var">sets_eq_let</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    allow specifying a particular hypothesis (by default,
    the first one that contains a <span class="inlinecode"><span class="id" type="keyword">let</span></span> is considered).

<div class="paragraph"> </div>

    Known limitation: it does not seem possible to support
    naming of multiple let-in constructs inside a term, from ltac. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">sets_let_base</span> <span class="id" type="var">tac</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">context</span>[<span class="id" type="keyword">let</span> <span class="id" type="var">_</span> := ?<span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">_</span>] ⇒ <span class="id" type="var">tac</span> <span class="id" type="var">E</span>; <span class="id" type="var">cbv</span> <span class="id" type="var">zeta</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">H</span>: <span class="id" type="var">context</span>[<span class="id" type="keyword">let</span> <span class="id" type="var">_</span> := ?<span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">_</span>] &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">tac</span> <span class="id" type="var">E</span>; <span class="id" type="var">cbv</span> <span class="id" type="var">zeta</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">sets_let_in_base</span> <span class="id" type="var">H</span> <span class="id" type="var">tac</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> <span class="id" type="var">context</span>[<span class="id" type="keyword">let</span> <span class="id" type="var">_</span> := ?<span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">_</span>] ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">tac</span> <span class="id" type="var">E</span>; <span class="id" type="var">cbv</span> <span class="id" type="var">zeta</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "sets_let" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sets_let_base</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">E</span> ⇒ <span class="id" type="var">sets</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_let" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sets_let_in_base</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">E</span> ⇒ <span class="id" type="var">sets</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq_let" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sets_let_base</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">E</span> ⇒ <span class="id" type="var">sets_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "sets_eq_let" <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sets_let_in_base</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">E</span> ⇒ <span class="id" type="var">sets_eq</span> <span class="id" type="var">X</span>: <span class="id" type="var">E</span>).<br/>
</div>

<div class="doc">
<a name="lab487"></a><h1 class="section">Rewriting</h1>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">rewrites</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is similar to <span class="inlinecode"><span class="id" type="tactic">rewrite</span></span> except that
    it supports the <span class="inlinecode"><span class="id" type="var">rm</span></span> directives to clear hypotheses
    on the fly, and that it supports a list of arguments in the form
    <span class="inlinecode"><span class="id" type="var">rewrites</span></span> <span class="inlinecode">(&gt;&gt;</span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>2</sub></span></span> <span class="inlinecode"><span class="id" type="var">E<sub>3</sub></span>)</span> to indicate that <span class="inlinecode"><span class="id" type="var">forwards</span></span> should be
    invoked first before <span class="inlinecode"><span class="id" type="var">rewrites</span></span> is called. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">List.list</span> <span class="id" type="var">Boxer</span> ⇒ <span class="id" type="var">forwards_then</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">cont</span> <span class="id" type="var">E</span>; <span class="id" type="var">fast_rm_inside</span> <span class="id" type="var">E</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">M</span> ).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">M</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">M</span> <span class="id" type="keyword">in</span> *).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">M</span> ).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">M</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">M</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">M</span> <span class="id" type="keyword">in</span> *).<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;--TODO:&nbsp;extend&nbsp;tactics&nbsp;below&nbsp;to&nbsp;use&nbsp;<span class="inlinecode"><span class="id" type="var">rewrites</span></span>&nbsp;*)</span><br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">rewrite_all</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> iterates version of <span class="inlinecode"><span class="id" type="tactic">rewrite</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> as long as possible.
    Warning: this tactic can easily get into an infinite loop.
    Syntax for rewriting from right to left and/or into an hypothese
    is similar to the one of <span class="inlinecode"><span class="id" type="tactic">rewrite</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">asserts_rewrite</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> asserts that an equality <span class="inlinecode"><span class="id" type="var">E</span></span> holds (generating a
    corresponding subgoal) and rewrite it straight away in the current
    goal. It avoids giving a name to the equality and later clearing it.
    Syntax for rewriting from right to left and/or into an hypothese
    is similar to the one of <span class="inlinecode"><span class="id" type="tactic">rewrite</span></span>. Note: the tactic <span class="inlinecode"><span class="id" type="var">replaces</span></span>
    plays a similar role. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">action</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">EQ</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> (<span class="id" type="tactic">assert</span> (<span class="id" type="var">EQ</span> : <span class="id" type="var">E</span>);<br/>
&nbsp;&nbsp;[ <span class="id" type="var">idtac</span> | <span class="id" type="var">action</span> <span class="id" type="var">EQ</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">EQ</span> ]).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">EQ</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">EQ</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> *).<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> *).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cuts_rewrite</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is the same as <span class="inlinecode"><span class="id" type="var">asserts_rewrite</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> except
    that subgoals are permuted. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">cuts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">action</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">EQ</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> (<span class="id" type="var">cuts</span> <span class="id" type="var">EQ</span>: <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;[ <span class="id" type="var">action</span> <span class="id" type="var">EQ</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">EQ</span> | <span class="id" type="var">idtac</span> ]).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">EQ</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">EQ</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">EQ</span> ⇒ <span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">rewrite_except</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="var">EQ</span></span> rewrites equality <span class="inlinecode"><span class="id" type="var">EQ</span></span> everywhere
    but in hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. Mainly useful for other tactics. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">rewrite_except</span> <span class="id" type="var">H</span> <span class="id" type="var">EQ</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">K</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">K</span> := <span class="id" type="var">T</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">EQ</span> <span class="id" type="keyword">in</span> *; <span class="id" type="tactic">unfold</span> <span class="id" type="var">K</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">K</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">rewrites</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> applies when <span class="inlinecode"><span class="id" type="var">E</span></span> is of the form <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">T<sub>2</sub></span></span>
    rewrites the equality <span class="inlinecode"><span class="id" type="var">E</span></span> at the <span class="inlinecode"><span class="id" type="var">K</span></span>-th occurence of <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span></span>
    in the current goal.
    Syntaxes <span class="inlinecode"><span class="id" type="var">rewrites</span></span> <span class="inlinecode">&lt;-</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> and <span class="inlinecode"><span class="id" type="var">rewrites</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    are also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "rewrites" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">T<sub>1</sub></span> = ?<span class="id" type="var">T<sub>2</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac_action_at</span> <span class="id" type="var">K</span> <span class="id" type="var">of</span> <span class="id" type="var">T<sub>1</sub></span> <span class="id" type="tactic">do</span> (<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">end</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">T<sub>1</sub></span> = ?<span class="id" type="var">T<sub>2</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac_action_at</span> <span class="id" type="var">K</span> <span class="id" type="var">of</span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="tactic">do</span> (<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span>) <span class="id" type="keyword">end</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">T<sub>1</sub></span> = ?<span class="id" type="var">T<sub>2</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac_action_at</span> <span class="id" type="var">K</span> <span class="id" type="var">of</span> <span class="id" type="var">T<sub>1</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="tactic">do</span> (<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>) <span class="id" type="keyword">end</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">T<sub>1</sub></span> = ?<span class="id" type="var">T<sub>2</sub></span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac_action_at</span> <span class="id" type="var">K</span> <span class="id" type="var">of</span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="tactic">do</span> (<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>) <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<a name="lab488"></a><h2 class="section">Replace</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">replaces</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">replace</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> except that
    the equality <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">F</span></span> is generated as first subgoal. Syntax
    <span class="inlinecode"><span class="id" type="var">replaces</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is also available. Note that contrary to
    <span class="inlinecode"><span class="id" type="tactic">replace</span></span>, <span class="inlinecode"><span class="id" type="var">replaces</span></span> does not try to solve the equality
    by <span class="inlinecode"><span class="id" type="tactic">assumption</span></span>. Note: <span class="inlinecode"><span class="id" type="var">replaces</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> is similar to
    <span class="inlinecode"><span class="id" type="var">asserts_rewrite</span></span> <span class="inlinecode">(<span class="id" type="var">E</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">F</span>)</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "replaces" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">F</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">assert</span> (<span class="id" type="var">T</span>: <span class="id" type="var">E</span> = <span class="id" type="var">F</span>); [ | <span class="id" type="tactic">replace</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> <span class="id" type="var">F</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">T</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "replaces" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">F</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">assert</span> (<span class="id" type="var">T</span>: <span class="id" type="var">E</span> = <span class="id" type="var">F</span>); [ | <span class="id" type="tactic">replace</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> <span class="id" type="var">F</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">T</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">replaces</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> replaces the <span class="inlinecode"><span class="id" type="var">K</span></span>-th occurence of <span class="inlinecode"><span class="id" type="var">E</span></span>
    with <span class="inlinecode"><span class="id" type="var">F</span></span> in the current goal. Syntax <span class="inlinecode"><span class="id" type="var">replaces</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="tactic">at</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode"><span class="id" type="var">F</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    is also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "replaces" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">F</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">assert</span> (<span class="id" type="var">T</span>: <span class="id" type="var">E</span> = <span class="id" type="var">F</span>); [ | <span class="id" type="var">rewrites</span> <span class="id" type="var">T</span> <span class="id" type="tactic">at</span> <span class="id" type="var">K</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">T</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "replaces" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "at" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">F</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">assert</span> (<span class="id" type="var">T</span>: <span class="id" type="var">E</span> = <span class="id" type="var">F</span>); [ | <span class="id" type="var">rewrites</span> <span class="id" type="var">T</span> <span class="id" type="tactic">at</span> <span class="id" type="var">K</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">T</span> ].<br/>
</div>

<div class="doc">
<a name="lab489"></a><h2 class="section">Change</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">changes</span></span> is like <span class="inlinecode"><span class="id" type="var">change</span></span> except that it does not silently
   fail to perform its task. (Note that, <span class="inlinecode"><span class="id" type="var">changes</span></span> is implemented
   using <span class="inlinecode"><span class="id" type="tactic">rewrite</span></span>, meaning that it might perform additional
   beta-reductions compared with the original <span class="inlinecode"><span class="id" type="var">change</span></span> tactic. 
</div>
<div class="code code-tight">
<span class="comment">(*&nbsp;--TODO:&nbsp;support&nbsp;"changes&nbsp;(E<sub>1</sub>&nbsp;=&nbsp;E<sub>2</sub>)"&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "changes" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> (<span class="id" type="var">E<sub>1</sub></span> = <span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; [ <span class="id" type="tactic">reflexivity</span> | ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "changes" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> (<span class="id" type="var">E<sub>1</sub></span> = <span class="id" type="var">E<sub>2</sub></span>); [ <span class="id" type="tactic">reflexivity</span> | ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "changes" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) "with" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> (<span class="id" type="var">E<sub>1</sub></span> = <span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="keyword">in</span> *; [ <span class="id" type="tactic">reflexivity</span> | ].<br/>
</div>

<div class="doc">
<a name="lab490"></a><h2 class="section">Renaming</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">renames</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">to</span></span> <span class="inlinecode"><span class="id" type="var">Y<sub>1</sub></span>,</span> <span class="inlinecode">...,</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> <span class="inlinecode"><span class="id" type="var">to</span></span> <span class="inlinecode"><span class="id" type="var">YN</span></span> is a shorthand for a sequence of
    renaming operations <span class="inlinecode"><span class="id" type="tactic">rename</span></span> <span class="inlinecode"><span class="id" type="var">Xi</span></span> <span class="inlinecode"><span class="id" type="var">into</span></span> <span class="inlinecode"><span class="id" type="var">Yi</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "renames" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rename</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">into</span> <span class="id" type="var">Y<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "renames" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>1</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">renames</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>1</sub></span>; <span class="id" type="var">renames</span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "renames" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>1</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>2</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">renames</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>1</sub></span>; <span class="id" type="var">renames</span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>2</sub></span>, <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "renames" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>1</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>2</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>3</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">renames</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>1</sub></span>; <span class="id" type="var">renames</span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>2</sub></span>, <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>3</sub></span>, <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "renames" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>1</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>2</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>3</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>4</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">renames</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>1</sub></span>; <span class="id" type="var">renames</span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>2</sub></span>, <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>3</sub></span>, <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>4</sub></span>, <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "renames" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>1</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>2</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>3</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>4</sub></span>) "," <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>5</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) "to" <span class="id" type="var">ident</span>(<span class="id" type="var">Y<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">renames</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>1</sub></span>; <span class="id" type="var">renames</span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>2</sub></span>, <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>3</sub></span>, <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>4</sub></span>, <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>5</sub></span>, <span class="id" type="var">X<sub>6</sub></span> <span class="id" type="var">to</span> <span class="id" type="var">Y<sub>6</sub></span>.<br/>
</div>

<div class="doc">
<a name="lab491"></a><h2 class="section">Unfolding</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">unfolds</span></span> unfolds the head definition in the goal, i.e. if the
    goal has form <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">xN</span></span> then it calls <span class="inlinecode"><span class="id" type="tactic">unfold</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span>.
    If the goal is an equality, it tries to unfold the head constant
    on the left-hand side, and otherwise tries on the right-hand side.
    If the goal is a product, it calls <span class="inlinecode"><span class="id" type="tactic">intros</span></span> first.
 warning: this tactic is overriden in LibReflect. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">apply_to_head_of</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">go</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">P</span> := <span class="id" type="var">get_head</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">cont</span> <span class="id" type="var">P</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>,_ ⇒ <span class="id" type="tactic">intros</span>; <span class="id" type="var">apply_to_head_of</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">A</span> = ?<span class="id" type="var">B</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="var">go</span> <span class="id" type="var">A</span> | <span class="id" type="var">go</span> <span class="id" type="var">B</span> ]<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">A</span> ⇒ <span class="id" type="var">go</span> <span class="id" type="var">A</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unfolds_base</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">G</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">apply_to_head_of</span> <span class="id" type="var">G</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">P</span> ⇒ <span class="id" type="tactic">unfold</span> <span class="id" type="var">P</span>) <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds_base</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">unfolds</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> unfolds the head definition of hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>, i.e. if
    <span class="inlinecode"><span class="id" type="var">H</span></span> has type <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">x<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">xN</span></span> then it calls <span class="inlinecode"><span class="id" type="tactic">unfold</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unfolds_in_base</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">G</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">apply_to_head_of</span> <span class="id" type="var">G</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">P</span> ⇒ <span class="id" type="tactic">unfold</span> <span class="id" type="var">P</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>) <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds_in_base</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">unfolds</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span>,<span class="id" type="var">H<sub>2</sub></span>,..,<span class="id" type="var">HN</span></span> allows unfolding the head constant
    in several hypotheses at once. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "unfolds" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">H<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>3</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">H<sub>3</sub></span> <span class="id" type="var">H<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>3</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>4</sub></span>) <span class="id" type="var">hyp</span>(<span class="id" type="var">H<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">unfolds</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">H<sub>3</sub></span> <span class="id" type="var">H<sub>4</sub></span> <span class="id" type="var">H<sub>5</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">unfolds</span></span> <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span>,..,<span class="id" type="var">PN</span></span> is a shortcut for <span class="inlinecode"><span class="id" type="tactic">unfold</span></span> <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span>,..,<span class="id" type="var">PN</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span>,<span class="id" type="var">F<sub>3</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span>,<span class="id" type="var">F<sub>3</sub></span>,<span class="id" type="var">F<sub>4</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span>,<span class="id" type="var">F<sub>3</sub></span>,<span class="id" type="var">F<sub>4</sub></span>,<span class="id" type="var">F<sub>5</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>5</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span>,<span class="id" type="var">F<sub>3</sub></span>,<span class="id" type="var">F<sub>4</sub></span>,<span class="id" type="var">F<sub>5</sub></span>,<span class="id" type="var">F<sub>6</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>5</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>6</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span>,<span class="id" type="var">F<sub>3</sub></span>,<span class="id" type="var">F<sub>4</sub></span>,<span class="id" type="var">F<sub>5</sub></span>,<span class="id" type="var">F<sub>6</sub></span>,<span class="id" type="var">F<sub>7</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>5</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>6</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>7</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">F<sub>1</sub></span>,<span class="id" type="var">F<sub>2</sub></span>,<span class="id" type="var">F<sub>3</sub></span>,<span class="id" type="var">F<sub>4</sub></span>,<span class="id" type="var">F<sub>5</sub></span>,<span class="id" type="var">F<sub>6</sub></span>,<span class="id" type="var">F<sub>7</sub></span>,<span class="id" type="var">F<sub>8</sub></span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">folds</span></span> <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span>,..,<span class="id" type="var">PN</span></span> is a shortcut for <span class="inlinecode"><span class="id" type="var">fold</span></span> <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*;</span> <span class="inlinecode">..;</span> <span class="inlinecode"><span class="id" type="var">fold</span></span> <span class="inlinecode"><span class="id" type="var">PN</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "folds" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fold</span> <span class="id" type="var">H</span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "folds" <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">folds</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "folds" <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">folds</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>2</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "folds" <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>3</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">folds</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>2</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>3</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "folds" <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>3</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">H<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">folds</span> <span class="id" type="var">H<sub>1</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>2</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>3</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>4</sub></span>; <span class="id" type="var">folds</span> <span class="id" type="var">H<sub>5</sub></span>.<br/>
</div>

<div class="doc">
<a name="lab492"></a><h2 class="section">Simplification</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">simpls</span></span> is a shortcut for <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "simpls" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">simpls</span></span> <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span>,..,<span class="id" type="var">PN</span></span> is a shortcut for
    <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*;</span> <span class="inlinecode">..;</span> <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> <span class="inlinecode"><span class="id" type="var">PN</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "simpls" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span> <span class="id" type="var">F<sub>1</sub></span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simpls" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>1</sub></span>; <span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simpls" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>1</sub></span>; <span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>2</sub></span>; <span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simpls" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>)<br/>
&nbsp;"," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>1</sub></span>; <span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>2</sub></span>; <span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>3</sub></span>; <span class="id" type="var">simpls</span> <span class="id" type="var">F<sub>4</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">unsimpl</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> replaces all occurence of <span class="inlinecode"><span class="id" type="var">X</span></span> by <span class="inlinecode"><span class="id" type="var">E</span></span>, where <span class="inlinecode"><span class="id" type="var">X</span></span> is
   the result which the tactic <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> would give when applied to <span class="inlinecode"><span class="id" type="var">E</span></span>.
   It is useful to undo what <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> has simplified too far. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "unsimpl" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">F</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">change</span> <span class="id" type="var">F</span> <span class="id" type="keyword">with</span> <span class="id" type="var">E</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">unsimpl</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is similar to <span class="inlinecode"><span class="id" type="var">unsimpl</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> but it applies
    inside a particular hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "unsimpl" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">F</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">change</span> <span class="id" type="var">F</span> <span class="id" type="keyword">with</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">unsimpl</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode">*</span> applies <span class="inlinecode"><span class="id" type="var">unsimpl</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> everywhere possible.
    <span class="inlinecode"><span class="id" type="var">unsimpls</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a synonymous. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "unsimpl" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">F</span> := (<span class="id" type="var">eval</span> <span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">change</span> <span class="id" type="var">F</span> <span class="id" type="keyword">with</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unsimpls" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unsimpl</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">nosimpl</span></span> <span class="inlinecode"><span class="id" type="var">t</span></span> protects the Coq term<span class="inlinecode"><span class="id" type="var">t</span></span> against some forms of
    simplification. See Gonthier's work for details on this trick. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Notation</span> "'nosimpl' t" := (<span class="id" type="keyword">match</span> <span class="id" type="var">tt</span> <span class="id" type="keyword">with</span> <span class="id" type="var">tt</span> ⇒ <span class="id" type="var">t</span> <span class="id" type="keyword">end</span>)<br/>
&nbsp;&nbsp;(<span class="id" type="tactic">at</span> <span class="id" type="var">level</span> 10).<br/>
</div>

<div class="doc">
<a name="lab493"></a><h2 class="section">Reduction</h2>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Tactic Notation</span> "hnfs" := <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<a name="lab494"></a><h2 class="section">Substitution</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">substs</span></span> does the same as <span class="inlinecode"><span class="id" type="tactic">subst</span></span>, except that it does not fail
    when there are circular equalities in the context. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "substs" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> (<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">x</span> = ?<span class="id" type="var">y</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span> | <span class="id" type="tactic">subst</span> <span class="id" type="var">y</span> ] <span class="id" type="keyword">end</span>).<br/>
</div>

<div class="doc">
Implementation of <span class="inlinecode"><span class="id" type="var">substs</span></span> <span class="inlinecode"><span class="id" type="var">below</span></span>, which allows to call
    <span class="inlinecode"><span class="id" type="tactic">subst</span></span> on all the hypotheses that lie beyond a given
    position in the proof context. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">substs_below</span> <span class="id" type="var">limit</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">limit</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">x</span> = ?<span class="id" type="var">y</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span>; <span class="id" type="var">substs_below</span> <span class="id" type="var">limit</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">subst</span> <span class="id" type="var">y</span>; <span class="id" type="var">substs_below</span> <span class="id" type="var">limit</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">generalizes</span> <span class="id" type="var">H</span>; <span class="id" type="var">substs_below</span> <span class="id" type="var">limit</span>; <span class="id" type="tactic">intro</span> ]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">substs</span></span> <span class="inlinecode"><span class="id" type="var">below</span></span> <span class="inlinecode"><span class="id" type="var">body</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> applies <span class="inlinecode"><span class="id" type="tactic">subst</span></span> on all equalities that appear
    in the context below the first hypothesis whose body is <span class="inlinecode"><span class="id" type="var">E</span></span>.
    If there is no such hypothesis in the context, it is equivalent
    to <span class="inlinecode"><span class="id" type="tactic">subst</span></span>. For instance, if <span class="inlinecode"><span class="id" type="var">H</span></span> is an hypothesis, then
    <span class="inlinecode"><span class="id" type="var">substs</span></span> <span class="inlinecode"><span class="id" type="var">below</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> will substitute equalities below hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "substs" "below" "body" <span class="id" type="var">constr</span>(<span class="id" type="var">M</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">substs_below</span> <span class="id" type="var">M</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">substs</span></span> <span class="inlinecode"><span class="id" type="var">below</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> applies <span class="inlinecode"><span class="id" type="tactic">subst</span></span> on all equalities that appear
    in the context below the hypothesis named <span class="inlinecode"><span class="id" type="var">H</span></span>. Note that
    the current implementation is technically incorrect since it
    will confuse different hypotheses with the same body. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "substs" "below" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">M</span> ⇒ <span class="id" type="var">substs</span> <span class="id" type="var">below</span> <span class="id" type="var">body</span> <span class="id" type="var">M</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">subst_hyp</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> substitutes the equality contained in the
    first hypothesis from the context. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">intro_subst_hyp</span> := <span class="id" type="tactic">fail</span>. <span class="comment">(*&nbsp;definition&nbsp;further&nbsp;on&nbsp;*)</span><br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">subst_hyp</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> substitutes the equality contained in <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">subst_hyp_base</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">_</span>,_,_,_,_) = (<span class="id" type="var">_</span>,_,_,_,_) ⇒ <span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">do</span> 4 <span class="id" type="var">intro_subst_hyp</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">_</span>,_,_,_) = (<span class="id" type="var">_</span>,_,_,_) ⇒ <span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">do</span> 4 <span class="id" type="var">intro_subst_hyp</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">_</span>,_,_) = (<span class="id" type="var">_</span>,_,_) ⇒ <span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">do</span> 3 <span class="id" type="var">intro_subst_hyp</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">_</span>,_) = (<span class="id" type="var">_</span>,_) ⇒ <span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">do</span> 2 <span class="id" type="var">intro_subst_hyp</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">x</span> = ?<span class="id" type="var">x</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">x</span> = ?<span class="id" type="var">y</span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span> | <span class="id" type="tactic">subst</span> <span class="id" type="var">y</span> ]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "subst_hyp" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) := <span class="id" type="var">subst_hyp_base</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">intro_subst_hyp</span> <span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intros</span> <span class="id" type="var">H</span>; <span class="id" type="var">subst_hyp</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">intro_subst</span></span> is a shorthand for <span class="inlinecode"><span class="id" type="tactic">intro</span></span> <span class="inlinecode"><span class="id" type="var">H</span>;</span> <span class="inlinecode"><span class="id" type="var">subst_hyp</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>:
    it introduces and substitutes the equality at the head
    of the current goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "intro_subst" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intros</span> <span class="id" type="var">H</span>; <span class="id" type="var">subst_hyp</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">subst_local</span></span> substitutes all local definition from the context 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">subst_local</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>:=_ &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">subst</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">subst_eq</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> takes an equality <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">t</span></span> and replace <span class="inlinecode"><span class="id" type="var">x</span></span>
    with <span class="inlinecode"><span class="id" type="var">t</span></span> everywhere in the goal 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">subst_eq_base</span> <span class="id" type="var">E</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; <span class="id" type="var">subst_hyp</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "subst_eq" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">subst_eq_base</span> <span class="id" type="var">E</span>.<br/>
</div>

<div class="doc">
<a name="lab495"></a><h2 class="section">Tactics to Work with Proof Irrelevance</h2>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">ProofIrrelevance</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">pi_rewrite</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> replaces <span class="inlinecode"><span class="id" type="var">E</span></span> of type <span class="inlinecode"><span class="id" type="keyword">Prop</span></span> with a fresh
    unification variable, and is thus a practical way to
    exploit proof irrelevance, without writing explicitly
    <span class="inlinecode"><span class="id" type="tactic">rewrite</span></span> <span class="inlinecode">(<span class="id" type="var">proof_irrelevance</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">E'</span>)</span>. Particularly useful
    when <span class="inlinecode"><span class="id" type="var">E'</span></span> is a big expression. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">pi_rewrite_base</span> <span class="id" type="var">E</span> <span class="id" type="var">rewrite_tac</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">E'</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">evar</span> (<span class="id" type="var">E'</span>:<span class="id" type="var">T</span>);<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_tac</span> (@<span class="id" type="var">proof_irrelevance</span> <span class="id" type="var">_</span> <span class="id" type="var">E</span> <span class="id" type="var">E'</span>); <span class="id" type="tactic">subst</span> <span class="id" type="var">E'</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "pi_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pi_rewrite_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">X</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">X</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "pi_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pi_rewrite_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">X</span> ⇒ <span class="id" type="tactic">rewrite</span> <span class="id" type="var">X</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>).<br/>
</div>

<div class="doc">
<a name="lab496"></a><h2 class="section">Proving Equalities</h2>

<div class="paragraph"> </div>

 Note: current implementation only supports up to arity 5 
<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">fequal</span></span> is a variation on <span class="inlinecode"><span class="id" type="tactic">f_equal</span></span> which has a better behaviour
    on equalities between n-ary tuples. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">fequal_base</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">go</span> := <span class="id" type="tactic">f_equal</span>; [ <span class="id" type="var">fequal_base</span> | ] <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">_</span>,_,_) = (<span class="id" type="var">_</span>,_,_) ⇒ <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">_</span>,_,_,_) = (<span class="id" type="var">_</span>,_,_,_) ⇒ <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">_</span>,_,_,_,_) = (<span class="id" type="var">_</span>,_,_,_,_) ⇒ <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">_</span>,_,_,_,_,_) = (<span class="id" type="var">_</span>,_,_,_,_,_) ⇒ <span class="id" type="var">go</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">f_equal</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fequal" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fequal_base</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">fequals</span></span> is the same as <span class="inlinecode"><span class="id" type="var">fequal</span></span> except that it tries and solve
    all trivial subgoals, using <span class="inlinecode"><span class="id" type="tactic">reflexivity</span></span> and <span class="inlinecode"><span class="id" type="tactic">congruence</span></span>
    (as well as the proof-irrelevance principle).
    <span class="inlinecode"><span class="id" type="var">fequals</span></span> applies to goals of the form <span class="inlinecode"><span class="id" type="var">f</span></span> <span class="inlinecode"><span class="id" type="var">x<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">xN</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">f</span></span> <span class="inlinecode"><span class="id" type="var">y<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">yN</span></span>
    and produces some subgoals of the form <span class="inlinecode"><span class="id" type="var">xi</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">yi</span></span>). 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">fequal_post</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">reflexivity</span> | <span class="id" type="tactic">congruence</span> | <span class="id" type="tactic">apply</span> <span class="id" type="var">proof_irrelevance</span> | <span class="id" type="var">idtac</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fequals" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fequal</span>; <span class="id" type="var">fequal_post</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">fequals_rec</span></span> calls <span class="inlinecode"><span class="id" type="var">fequals</span></span> recursively.
    It is equivalent to <span class="inlinecode"><span class="id" type="tactic">repeat</span></span> <span class="inlinecode">(<span class="id" type="tactic">progress</span></span> <span class="inlinecode"><span class="id" type="var">fequals</span>)</span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "fequals_rec" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> (<span class="id" type="tactic">progress</span> <span class="id" type="var">fequals</span>).<br/>
</div>

<div class="doc">
<a name="lab497"></a><h1 class="section">Inversion</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab498"></a><h2 class="section">Basic Inversion</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is same to <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> except that it puts all the
    facts obtained in the goal. The keyword <span class="inlinecode"><span class="id" type="var">keep</span></span> means that the
    hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span> should not be removed. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "invert" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pose</span> <span class="id" type="var">ltac_mark</span>; <span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="var">gen_until_mark</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode">...</span> except
    that only hypotheses which are not variable need to be named
    explicitely, in a similar fashion as <span class="inlinecode"><span class="id" type="var">introv</span></span> is used to name
    only hypotheses. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "invert" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "invert" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "invert" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is same to <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> except that it puts all the
    facts obtained in the goal and clears hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>.
    In other words, it is equivalent to <span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span>;</span> <span class="inlinecode"><span class="id" type="tactic">clear</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "invert" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is the same as <span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span>
    but it also clears hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "invert_tactic" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">tactic</span>(<span class="id" type="var">tac</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H'</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">rename</span> <span class="id" type="var">H</span> <span class="id" type="var">into</span> <span class="id" type="var">H'</span>; <span class="id" type="var">tac</span> <span class="id" type="var">H'</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H'</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "invert" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "invert" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "invert" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>).<br/>
</div>

<div class="doc">
<a name="lab499"></a><h2 class="section">Inversion with Substitution</h2>

<div class="paragraph"> </div>

 Our inversion tactics is able to get rid of dependent equalities
    generated by <span class="inlinecode"><span class="id" type="tactic">inversion</span></span>, using proof irrelevance. 
</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;--we&nbsp;do&nbsp;not&nbsp;import&nbsp;Eqdep&nbsp;because&nbsp;it&nbsp;imports&nbsp;nasty&nbsp;hints&nbsp;automatically<br/>
&nbsp;&nbsp;&nbsp;&nbsp;From&nbsp;TLC&nbsp;Require&nbsp;Import&nbsp;Eqdep.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Axiom</span> <span class="id" type="var">inj_pair2</span> :  <span class="comment">(*&nbsp;is&nbsp;in&nbsp;fact&nbsp;derivable&nbsp;from&nbsp;the&nbsp;axioms&nbsp;in&nbsp;LibAxiom.v&nbsp;*)</span><br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">U</span> : <span class="id" type="keyword">Type</span>) (<span class="id" type="var">P</span> : <span class="id" type="var">U</span> → <span class="id" type="keyword">Type</span>) (<span class="id" type="var">p</span> : <span class="id" type="var">U</span>) (<span class="id" type="var">x</span> <span class="id" type="var">y</span> : <span class="id" type="var">P</span> <span class="id" type="var">p</span>),<br/>
&nbsp;&nbsp;<span class="id" type="var">existT</span> <span class="id" type="var">P</span> <span class="id" type="var">p</span> <span class="id" type="var">x</span> = <span class="id" type="var">existT</span> <span class="id" type="var">P</span> <span class="id" type="var">p</span> <span class="id" type="var">y</span> → <span class="id" type="var">x</span> = <span class="id" type="var">y</span>.<br/>
<span class="comment">(*&nbsp;Proof&nbsp;using.&nbsp;apply&nbsp;Eqdep.EqdepTheory.inj_pair2.&nbsp;Qed.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">i<sub>1</sub></span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">i<sub>1</sub></span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">ltac_Mark</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="tactic">intros</span> <span class="id" type="var">_</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (?<span class="id" type="var">x</span> = ?<span class="id" type="var">y</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intro</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span> | <span class="id" type="tactic">subst</span> <span class="id" type="var">y</span> ];<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">i<sub>1</sub></span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">existT</span> ?<span class="id" type="var">P</span> ?<span class="id" type="var">p</span> ?<span class="id" type="var">x</span> = <span class="id" type="var">existT</span> ?<span class="id" type="var">P</span> ?<span class="id" type="var">p</span> ?<span class="id" type="var">y</span> → <span class="id" type="var">_</span>) ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intro</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> (@<span class="id" type="var">inj_pair2</span> <span class="id" type="var">_</span> <span class="id" type="var">P</span> <span class="id" type="var">p</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span> <span class="id" type="var">H</span>);<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="var">go</span> <span class="id" type="var">i<sub>1</sub></span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (?<span class="id" type="var">P</span> → ?<span class="id" type="var">Q</span>) ⇒ <span class="id" type="var">i<sub>1</sub></span>; <span class="id" type="var">go</span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span>) ⇒ <span class="id" type="tactic">intro</span>; <span class="id" type="var">go</span> <span class="id" type="var">i<sub>1</sub></span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">ltac_mark</span>; <span class="id" type="var">invert</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span>; <span class="id" type="var">go</span> <span class="id" type="var">i<sub>1</sub></span> <span class="id" type="var">i<sub>2</sub></span> <span class="id" type="var">i<sub>3</sub></span> <span class="id" type="var">i<sub>4</sub></span> <span class="id" type="var">i<sub>5</sub></span> <span class="id" type="var">i<sub>6</sub></span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">eq'</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is same to <span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> except that it
    applies <span class="inlinecode"><span class="id" type="tactic">subst</span></span> to all the equalities generated by the inversion. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is the same as
    <span class="inlinecode"><span class="id" type="var">invert</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> except that it applies <span class="inlinecode"><span class="id" type="tactic">subst</span></span> to all the
    equalities generated by the inversion 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>2</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>5</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intro</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_tactic</span> <span class="id" type="var">H</span> <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>1</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>3</sub></span>)<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>4</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>5</sub></span>) <span class="id" type="var">ltac</span>:(<span class="id" type="tactic">intros</span> <span class="id" type="var">I<sub>6</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is same to <span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> except that it
    clears hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">try</span> <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is the same as <span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span>
    but it also clears the hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inverts_tactic" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">tactic</span>(<span class="id" type="var">tac</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H'</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">rename</span> <span class="id" type="var">H</span> <span class="id" type="var">into</span> <span class="id" type="var">H'</span>; <span class="id" type="var">tac</span> <span class="id" type="var">H'</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H'</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert_tactic</span> <span class="id" type="var">H</span> (<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">keep</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span>).<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> performs an inversion on hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>, substitutes
    generated equalities, and put in the goal the other freshly-created
    hypotheses, for the user to name explicitly.
    <span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> is the same except that it does not clear <span class="inlinecode"><span class="id" type="var">H</span></span>.
TODO: reimplement <span class="inlinecode"><span class="id" type="var">inverts</span></span> above using this one 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">inverts_as_tactic</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">tt</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">ltac_Mark</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="tactic">intros</span> <span class="id" type="var">_</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (?<span class="id" type="var">x</span> = ?<span class="id" type="var">y</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intro</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span> | <span class="id" type="tactic">subst</span> <span class="id" type="var">y</span> ];<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">tt</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">existT</span> ?<span class="id" type="var">P</span> ?<span class="id" type="var">p</span> ?<span class="id" type="var">x</span> = <span class="id" type="var">existT</span> ?<span class="id" type="var">P</span> ?<span class="id" type="var">p</span> ?<span class="id" type="var">y</span> → <span class="id" type="var">_</span>) ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intro</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> (@<span class="id" type="var">inj_pair2</span> <span class="id" type="var">_</span> <span class="id" type="var">P</span> <span class="id" type="var">p</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span> <span class="id" type="var">H</span>);<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="var">go</span> <span class="id" type="var">tt</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span style='font-size:120%;'>&forall;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span>) ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">intro</span>; <span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="var">get_last_hyp</span> <span class="id" type="var">tt</span> <span class="id" type="keyword">in</span> <span class="id" type="var">mark_to_generalize</span> <span class="id" type="var">H</span>; <span class="id" type="var">go</span> <span class="id" type="var">tt</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">pose</span> <span class="id" type="var">ltac_mark</span>; <span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">ltac_mark</span>; <span class="id" type="var">gen_until_mark</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">tt</span>; <span class="id" type="var">gen_to_generalize</span>; <span class="id" type="var">unfolds</span> <span class="id" type="var">ltac_to_generalize</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">eq'</span> <span class="id" type="keyword">in</span> *.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_as_tactic</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts_as_tactic</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>5</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>6</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>7</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span>; <span class="id" type="var">introv</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span> <span class="id" type="var">I<sub>5</sub></span> <span class="id" type="var">I<sub>6</sub></span> <span class="id" type="var">I<sub>7</sub></span> <span class="id" type="var">I<sub>8</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">lets_inverts</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">I<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">IN</span></span> is intuitively equivalent to
    <span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span>, with the difference that it applies to any
    expression and not just to the name of an hypothesis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">lets_inverts_base</span> <span class="id" type="var">E</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; <span class="id" type="tactic">try</span> <span class="id" type="var">cont</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets_inverts" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets_inverts_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">H</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets_inverts" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets_inverts_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets_inverts" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets_inverts_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets_inverts" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets_inverts_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets_inverts" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>1</sub></span>)<br/>
&nbsp;<span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>2</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>3</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets_inverts_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">H</span> ⇒ <span class="id" type="var">inverts</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I<sub>1</sub></span> <span class="id" type="var">I<sub>2</sub></span> <span class="id" type="var">I<sub>3</sub></span> <span class="id" type="var">I<sub>4</sub></span>).<br/>
</div>

<div class="doc">
<a name="lab500"></a><h2 class="section">Injection with Substitution</h2>

<div class="paragraph"> </div>

 Underlying implementation of <span class="inlinecode"><span class="id" type="var">injects</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">injects_tactic</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">go</span> <span class="id" type="var">_</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (<span class="id" type="var">ltac_Mark</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="tactic">intros</span> <span class="id" type="var">_</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| &#x22A2; (?<span class="id" type="var">x</span> = ?<span class="id" type="var">y</span> → <span class="id" type="var">_</span>) ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="tactic">intro</span> <span class="id" type="var">H</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">subst</span> <span class="id" type="var">x</span> | <span class="id" type="tactic">subst</span> <span class="id" type="var">y</span> | <span class="id" type="var">idtac</span> ];<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">go</span> <span class="id" type="var">tt</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">ltac_mark</span>; <span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="var">go</span> <span class="id" type="var">tt</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">injects</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> takes an hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span> of the form
    <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">a<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">aN</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">C</span></span> <span class="inlinecode"><span class="id" type="var">b<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">bN</span></span> and substitute all equalities
    <span class="inlinecode"><span class="id" type="var">ai</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">bi</span></span> that have been generated. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "injects" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">injects_tactic</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">injects</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is similar to <span class="inlinecode"><span class="id" type="var">injects</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> but clears
    the hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "injects" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">injects_tactic</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inject</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">injection</span></span>
    followed by <span class="inlinecode"><span class="id" type="tactic">intros</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inject" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inject" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">X<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inject" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inject" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inject" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inject" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span>.<br/>
</div>

<div class="doc">
<a name="lab501"></a><h2 class="section">Inversion and Injection with Substitution &mdash;rough implementation</h2>

<div class="paragraph"> </div>

 The tactics <span class="inlinecode"><span class="id" type="var">inversions</span></span> and <span class="inlinecode"><span class="id" type="var">injections</span></span> provided in this section
    are similar to <span class="inlinecode"><span class="id" type="var">inverts</span></span> and <span class="inlinecode"><span class="id" type="var">injects</span></span> except that they perform
    substitution on all equalities from the context and not only
    the ones freshly generated. The counterpart is that they have
    simpler implementations.

<div class="paragraph"> </div>

    DEPRECATED: these tactics should no longer be used. 
<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">inversions</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is the same as <span class="inlinecode"><span class="id" type="var">inversions</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> but it does
    not clear hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inversions" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">subst</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">inversions</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is a shortcut for <span class="inlinecode"><span class="id" type="tactic">inversion</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> followed by <span class="inlinecode"><span class="id" type="tactic">subst</span></span>
    and <span class="inlinecode"><span class="id" type="tactic">clear</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>.
    It is a rough implementation of <span class="inlinecode"><span class="id" type="var">inverts</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> which behave
    badly when the proof context already contains equalities.
    It is provided in case the better implementation turns out to be
    too slow. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "inversions" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">subst</span>; <span class="id" type="tactic">try</span> <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">injections</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">injection</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> followed
    by <span class="inlinecode"><span class="id" type="tactic">intros</span></span> and <span class="inlinecode"><span class="id" type="tactic">subst</span></span>. It is a rough implementation of
    <span class="inlinecode"><span class="id" type="var">injects</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> which behave
    badly when the proof context already contains equalities,
    or when the goal starts with a forall or an implication. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "injections" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span>; <span class="id" type="tactic">subst</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">injections</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is the same as <span class="inlinecode"><span class="id" type="tactic">injection</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> followed
    by <span class="inlinecode"><span class="id" type="tactic">clear</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> and <span class="inlinecode"><span class="id" type="tactic">intros</span></span> and <span class="inlinecode"><span class="id" type="tactic">subst</span></span>. It is a rough
    implementation of <span class="inlinecode"><span class="id" type="var">injects</span></span> <span class="inlinecode"><span class="id" type="var">keep</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> which behave
    badly when the proof context already contains equalities,
    or when the goal starts with a forall or an implication. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "injections" "keep" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">injection</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">intros</span>; <span class="id" type="tactic">subst</span>.<br/>
</div>

<div class="doc">
<a name="lab502"></a><h2 class="section">Case Analysis</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">cases</span></span> is similar to <span class="inlinecode"><span class="id" type="var">case_eq</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> except that it generates the
    equality in the context and not in the goal, and generates the
    equality the other way round. The syntax <span class="inlinecode"><span class="id" type="var">cases</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    allows specifying the name <span class="inlinecode"><span class="id" type="var">H</span></span> of that hypothesis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "cases" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> *; <span class="id" type="var">def_to_eq_sym</span> <span class="id" type="var">X</span> <span class="id" type="var">H</span> <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">X</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "Eq" <span class="id" type="keyword">in</span> <span class="id" type="var">cases</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">case_if_post</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is to be defined later as a tactic to clean
    up hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span> and the goal.
    By defaults, it looks for obvious contradictions.
    Currently, this tactic is extended in LibReflect to clean up
    boolean propositions. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">case_if_post</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">tryfalse</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">case_if</span></span> looks for a pattern of the form <span class="inlinecode"><span class="id" type="keyword">if</span></span> <span class="inlinecode">?<span class="id" type="var">B</span></span> <span class="inlinecode"><span class="id" type="keyword">then</span></span> <span class="inlinecode">?<span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="keyword">else</span></span> <span class="inlinecode">?<span class="id" type="var">E<sub>2</sub></span></span>
    in the goal, and perform a case analysis on <span class="inlinecode"><span class="id" type="var">B</span></span> by calling
    <span class="inlinecode"><span class="id" type="tactic">destruct</span></span> <span class="inlinecode"><span class="id" type="var">B</span></span>. Subgoals containing a contradiction are discarded.
    <span class="inlinecode"><span class="id" type="var">case_if</span></span> looks in the goal first, and otherwise in the
    first hypothesis that contains an <span class="inlinecode"><span class="id" type="keyword">if</span></span> statement.
    <span class="inlinecode"><span class="id" type="var">case_if</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> can be used to specify which hypothesis to consider.
    Syntaxes <span class="inlinecode"><span class="id" type="var">case_if</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">Eq</span></span> and <span class="inlinecode"><span class="id" type="var">case_if</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">Eq</span></span> allows to name
    the hypothesis coming from the case analysis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">case_if_on_tactic_core</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| {<span class="id" type="var">_</span>}+{_} ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">Eq</span> | <span class="id" type="var">Eq</span>]<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">sets_eq</span> &lt;- <span class="id" type="var">X</span> <span class="id" type="var">Eq</span>: <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">X</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">case_if_on_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_if_on_tactic_core</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span>; <span class="id" type="var">case_if_post</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "case_if_on" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_if_on_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒ <span class="id" type="var">case_if_on</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">K</span>: <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">case_if_on</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">case_if_on</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">case_if</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">case_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cases_if</span></span> is similar to <span class="inlinecode"><span class="id" type="var">case_if</span></span> with two main differences:
    if it creates an equality of the form <span class="inlinecode"><span class="id" type="var">x</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">y</span></span> and then
    substitutes it in the goal 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">cases_if_on_tactic_core</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| {<span class="id" type="var">_</span>}+{_} ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">Eq</span>|<span class="id" type="var">Eq</span>]; <span class="id" type="tactic">try</span> <span class="id" type="var">subst_hyp</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">sets_eq</span> &lt;- <span class="id" type="var">X</span> <span class="id" type="var">Eq</span>: <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">X</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">cases_if_on_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if_on_tactic_core</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span>; <span class="id" type="var">tryfalse</span>; <span class="id" type="var">case_if_post</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if_on" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if_on_tactic</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒ <span class="id" type="var">cases_if_on</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">K</span>: <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">cases_if_on</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">cases_if_on</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">cases_if</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">cases_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">case_ifs</span></span> is like <span class="inlinecode"><span class="id" type="tactic">repeat</span></span> <span class="inlinecode"><span class="id" type="var">case_if</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">case_ifs_core</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="var">case_if</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "case_ifs" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_ifs_core</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">destruct_if</span></span> looks for a pattern of the form <span class="inlinecode"><span class="id" type="keyword">if</span></span> <span class="inlinecode">?<span class="id" type="var">B</span></span> <span class="inlinecode"><span class="id" type="keyword">then</span></span> <span class="inlinecode">?<span class="id" type="var">E<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="keyword">else</span></span> <span class="inlinecode">?<span class="id" type="var">E<sub>2</sub></span></span>
    in the goal, and perform a case analysis on <span class="inlinecode"><span class="id" type="var">B</span></span> by calling
    <span class="inlinecode"><span class="id" type="tactic">destruct</span></span> <span class="inlinecode"><span class="id" type="var">B</span></span>. It looks in the goal first, and otherwise in the
    first hypothesis that contains an <span class="inlinecode"><span class="id" type="keyword">if</span></span> statement. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">destruct_if_post</span> := <span class="id" type="var">tryfalse</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if"<br/>
&nbsp;"as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">Eq<sub>1</sub></span>|<span class="id" type="var">Eq<sub>2</sub></span>]<br/>
&nbsp;&nbsp;| <span class="id" type="var">K</span>: <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">Eq<sub>1</sub></span>|<span class="id" type="var">Eq<sub>2</sub></span>]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if_post</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>)<br/>
&nbsp;"as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span> <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">B</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">Eq<sub>1</sub></span>|<span class="id" type="var">Eq<sub>2</sub></span>] <span class="id" type="keyword">end</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if_post</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span> <span class="id" type="var">Eq</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">destruct_if</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span> <span class="id" type="var">Eq</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">destruct_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span> <span class="id" type="var">Eq</span>.<br/>
</div>

<div class="doc">
BROKEN since v<sub>8</sub>.5beta2. TODO: cleanup.

<div class="paragraph"> </div>

    <span class="inlinecode"><span class="id" type="var">destruct_head_match</span></span> performs a case analysis on the argument
    of the head pattern matching when the goal has the form
    <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode">?<span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode">...</span> or <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode">?<span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode">...</span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="var">_</span></span> or
    <span class="inlinecode"><span class="id" type="var">_</span></span> <span class="inlinecode">=</span> <span class="inlinecode"><span class="id" type="keyword">match</span></span> <span class="inlinecode">?<span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">with</span></span> <span class="inlinecode">...</span>. Due to the limits of Ltac, this tactic
    will not fail if a match does not occur. Instead, it might
    perform a case analysis on an unspecified subterm from the goal.
    Warning: experimental. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">find_head_match</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span> <span class="id" type="var">context</span> [?<span class="id" type="var">E</span>] ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">E</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(<span class="id" type="var">E</span>)<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">destruct_head_match_core</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">T<sub>1</sub></span> = ?<span class="id" type="var">T<sub>2</sub></span> ⇒ <span class="id" type="var">first</span> [ <span class="id" type="keyword">let</span> <span class="id" type="var">E</span> := <span class="id" type="var">find_head_match</span> <span class="id" type="var">T<sub>1</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">cont</span> <span class="id" type="var">E</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="keyword">let</span> <span class="id" type="var">E</span> := <span class="id" type="var">find_head_match</span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">cont</span> <span class="id" type="var">E</span> ]<br/>
&nbsp;&nbsp;| &#x22A2; ?<span class="id" type="var">T<sub>1</sub></span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">E</span> := <span class="id" type="var">find_head_match</span> <span class="id" type="var">T<sub>1</sub></span> <span class="id" type="keyword">in</span> <span class="id" type="var">cont</span> <span class="id" type="var">E</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if_post</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_head_match" "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_head_match_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">E</span> ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_head_match" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_head_match_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">E</span> ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">E</span>).<br/><hr class='doublespaceincode'/>
<span class="comment">(**--provided&nbsp;for&nbsp;compatibility&nbsp;with&nbsp;<span class="inlinecode"><span class="id" type="var">remember</span></span>&nbsp;*)</span><br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cases'</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is similar to <span class="inlinecode"><span class="id" type="var">case_eq</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> except that it generates the
    equality in the context and not in the goal. The syntax <span class="inlinecode"><span class="id" type="var">cases'</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    allows specifying the name <span class="inlinecode"><span class="id" type="var">H</span></span> of that hypothesis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "cases'" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">set</span> (<span class="id" type="var">X</span> := <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> *; <span class="id" type="var">def_to_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">H</span> <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">X</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases'" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">x</span> := <span class="id" type="tactic">fresh</span> "Eq" <span class="id" type="keyword">in</span> <span class="id" type="var">cases'</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">cases_if'</span></span> is similar to <span class="inlinecode"><span class="id" type="var">cases_if</span></span> except that it generates
    the symmetric equality. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">cases_if_on'</span> <span class="id" type="var">E</span> <span class="id" type="var">Eq</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| {<span class="id" type="var">_</span>}+{_} ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">Eq</span>|<span class="id" type="var">Eq</span>]; <span class="id" type="tactic">try</span> <span class="id" type="var">subst_hyp</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">X</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">sets_eq</span> <span class="id" type="var">X</span> <span class="id" type="var">Eq</span>: <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">X</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>; <span class="id" type="var">case_if_post</span> <span class="id" type="var">Eq</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if'" "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">Eq</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] ⇒ <span class="id" type="var">cases_if_on'</span> <span class="id" type="var">B</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">K</span>: <span class="id" type="var">context</span> [<span class="id" type="keyword">if</span> ?<span class="id" type="var">B</span> <span class="id" type="keyword">then</span> <span class="id" type="var">_</span> <span class="id" type="keyword">else</span> <span class="id" type="var">_</span>] &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">cases_if_on'</span> <span class="id" type="var">B</span> <span class="id" type="var">Eq</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if'" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">Eq</span> := <span class="id" type="tactic">fresh</span> "C" <span class="id" type="keyword">in</span> <span class="id" type="var">cases_if'</span> <span class="id" type="keyword">as</span> <span class="id" type="var">Eq</span>.<br/>
</div>

<div class="doc">
<a name="lab503"></a><h1 class="section">Induction</h1>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">inductions</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> is a shorthand for <span class="inlinecode"><span class="id" type="tactic">dependent</span></span> <span class="inlinecode"><span class="id" type="tactic">induction</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span>.
    <span class="inlinecode"><span class="id" type="var">inductions</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">gen</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is a shorthand for
    <span class="inlinecode"><span class="id" type="tactic">dependent</span></span> <span class="inlinecode"><span class="id" type="tactic">induction</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">generalizing</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Program.Equality</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">inductions_post</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">eq'</span> <span class="id" type="keyword">in</span> *.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">X<sub>6</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>7</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">X<sub>6</sub></span> <span class="id" type="var">X<sub>7</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inductions" <span class="id" type="var">ident</span>(<span class="id" type="var">E</span>) "gen" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>7</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>8</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">dependent</span> <span class="id" type="tactic">induction</span> <span class="id" type="var">E</span> <span class="id" type="var">generalizing</span> <span class="id" type="var">X<sub>1</sub></span> <span class="id" type="var">X<sub>2</sub></span> <span class="id" type="var">X<sub>3</sub></span> <span class="id" type="var">X<sub>4</sub></span> <span class="id" type="var">X<sub>5</sub></span> <span class="id" type="var">X<sub>6</sub></span> <span class="id" type="var">X<sub>7</sub></span> <span class="id" type="var">X<sub>8</sub></span>; <span class="id" type="var">inductions_post</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">induction_wf</span></span> <span class="inlinecode"><span class="id" type="var">IH</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> is used to apply the well-founded induction
    principle, for a given well-founded relation. It applies to a goal
    <span class="inlinecode"><span class="id" type="var">PX</span></span> where <span class="inlinecode"><span class="id" type="var">PX</span></span> is a proposition on <span class="inlinecode"><span class="id" type="var">X</span></span>. First, it sets up the
    goal in the form <span class="inlinecode">(<span class="id" type="keyword">fun</span></span> <span class="inlinecode"><span class="id" type="var">a</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode"><span class="id" type="var">a</span>)</span> <span class="inlinecode"><span class="id" type="var">X</span></span>, using <span class="inlinecode"><span class="id" type="tactic">pattern</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span>, and then
    it applies the well-founded induction principle instantiated on <span class="inlinecode"><span class="id" type="var">E</span></span>.

<div class="paragraph"> </div>

    Here <span class="inlinecode"><span class="id" type="var">E</span></span> may be either:

<div class="paragraph"> </div>

<ul class="doclist">
<li> a proof of <span class="inlinecode"><span class="id" type="keyword">wf</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> for <span class="inlinecode"><span class="id" type="var">R</span></span> of type <span class="inlinecode"><span class="id" type="var">A</span>→<span class="id" type="var">A</span>→<span class="id" type="keyword">Prop</span></span>

</li>
<li> a binary relation of type <span class="inlinecode"><span class="id" type="var">A</span>→<span class="id" type="var">A</span>→<span class="id" type="keyword">Prop</span></span>

</li>
<li> a measure of type <span class="inlinecode"><span class="id" type="var">A</span></span> <span class="inlinecode">→</span> <span class="inlinecode"><span class="id" type="var">nat</span></span> // only when LibWf is used

<div class="paragraph"> </div>

    Syntaxes <span class="inlinecode"><span class="id" type="var">induction_wf</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span> and <span class="inlinecode"><span class="id" type="var">induction_wf</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">X</span></span>. 
</li>
</ul>

</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;DEPRECATED<br/>
Tactic&nbsp;Notation&nbsp;"induction_wf"&nbsp;ident(IH)&nbsp;":"&nbsp;constr(E)&nbsp;ident(X)&nbsp;:=<br/>
&nbsp;&nbsp;pattern&nbsp;X;&nbsp;apply&nbsp;(well_founded_ind&nbsp;E);&nbsp;clear&nbsp;X;&nbsp;intros&nbsp;X&nbsp;IH.<br/>
*)</span><br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;Tactic&nbsp;is&nbsp;later&nbsp;extended&nbsp;in&nbsp;module&nbsp;LibWf&nbsp;*)</span><br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">induction_wf_core_then</span> <span class="id" type="var">IH</span> <span class="id" type="var">E</span> <span class="id" type="var">X</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">eval</span> <span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">clearX</span> <span class="id" type="var">tt</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">clear</span> <span class="id" type="var">X</span> | <span class="id" type="tactic">fail</span> 3 "the variable on which the induction is done appears in the hypotheses" ] <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;Support&nbsp;for&nbsp;measures&nbsp;from&nbsp;LibWf,&nbsp;add&nbsp;this:<br/>
&nbsp;&nbsp;|&nbsp;?A&nbsp;<span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span>&nbsp;nat&nbsp;=&gt;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;induction_wf_core_then&nbsp;IH&nbsp;(wf_measure&nbsp;E)&nbsp;X&nbsp;cont<br/>
&nbsp;&nbsp;*)</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">A</span> → ?<span class="id" type="var">A</span> → <span class="id" type="keyword">Prop</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">pattern</span> <span class="id" type="var">X</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">well_founded_ind</span> <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">clearX</span> <span class="id" type="var">tt</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ <span class="comment">(*&nbsp;Support&nbsp;for&nbsp;<span class="inlinecode"><span class="id" type="keyword">wf</span></span>&nbsp;from&nbsp;LibWf<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;change&nbsp;well_founded&nbsp;with&nbsp;wf;&nbsp;auto&nbsp;with&nbsp;wf&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">intros</span> <span class="id" type="var">X</span> <span class="id" type="var">IH</span>; <span class="id" type="var">cont</span> <span class="id" type="var">tt</span> ]<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="tactic">fail</span> 2 ]<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">pattern</span> <span class="id" type="var">X</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">well_founded_ind</span> <span class="id" type="var">E</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">clearX</span> <span class="id" type="var">tt</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">intros</span> <span class="id" type="var">X</span> <span class="id" type="var">IH</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">cont</span> <span class="id" type="var">tt</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">induction_wf_core</span> <span class="id" type="var">IH</span> <span class="id" type="var">E</span> <span class="id" type="var">X</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">induction_wf_core_then</span> <span class="id" type="var">IH</span> <span class="id" type="var">E</span> <span class="id" type="var">X</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "induction_wf" <span class="id" type="var">ident</span>(<span class="id" type="var">IH</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">induction_wf_core</span> <span class="id" type="var">IH</span> <span class="id" type="var">E</span> <span class="id" type="var">X</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "induction_wf" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">IH</span> := <span class="id" type="tactic">fresh</span> "IH" <span class="id" type="keyword">in</span> <span class="id" type="var">induction_wf</span> <span class="id" type="var">IH</span>: <span class="id" type="var">E</span> <span class="id" type="var">X</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "induction_wf" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">induction_wf</span>: <span class="id" type="var">E</span> <span class="id" type="var">X</span>.<br/>
</div>

<div class="doc">
Induction on the height of a derivation: the helper tactic
    <span class="inlinecode"><span class="id" type="var">induct_height</span></span> helps proving the equivalence of the auxiliary
    judgment that includes a counter for the maximal height
    (see LibTacticsDemos for an example) 
</div>
<div class="code code-tight">

<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">Arith.Compare_dec</span>.<br/>
<span class="id" type="var">From</span> <span class="id" type="var">Coq</span> <span class="id" type="keyword">Require</span> <span class="id" type="keyword">Import</span> <span class="id" type="var">omega.Omega</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">induct_height_max2</span> : <span style='font-size:120%;'>&forall;</span><span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> : <span class="id" type="var">nat</span>,<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">n</span>, <span class="id" type="var">n<sub>1</sub></span> &lt; <span class="id" type="var">n</span> ∧ <span class="id" type="var">n<sub>2</sub></span> &lt; <span class="id" type="var">n</span>.<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>.<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intros</span>. <span class="id" type="tactic">destruct</span> (<span class="id" type="var">lt_dec</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>).<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">S</span> <span class="id" type="var">n<sub>2</sub></span>). <span class="id" type="tactic">omega</span>.<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">S</span> <span class="id" type="var">n<sub>1</sub></span>). <span class="id" type="tactic">omega</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">induct_height_step</span> <span class="id" type="var">x</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">H</span>: <span style='font-size:120%;'>&exist;</span><span class="id" type="var">_</span>, <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">n</span> := <span class="id" type="tactic">fresh</span> "n" <span class="id" type="keyword">in</span> <span class="id" type="keyword">let</span> <span class="id" type="var">y</span> := <span class="id" type="tactic">fresh</span> "x" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">n</span> ?];<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">forwards</span> (<span class="id" type="var">y</span>&amp;?&amp;?): <span class="id" type="var">induct_height_max2</span> <span class="id" type="var">n</span> <span class="id" type="var">x</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">induct_height_step</span> <span class="id" type="var">y</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">S</span> <span class="id" type="var">x</span>); <span class="id" type="tactic">eauto</span><br/>
&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">induct_height</span> := <span class="id" type="var">induct_height_step</span> <span class="id" type="var">O</span>.<br/>
</div>

<div class="doc">
<a name="lab504"></a><h1 class="section">Coinduction</h1>

<div class="paragraph"> </div>

 Tactic <span class="inlinecode"><span class="id" type="var">cofixs</span></span> <span class="inlinecode"><span class="id" type="var">IH</span></span> is like <span class="inlinecode"><span class="id" type="var">cofix</span></span> <span class="inlinecode"><span class="id" type="var">IH</span></span> except that the
    coinduction hypothesis is tagged in the form <span class="inlinecode"><span class="id" type="var">IH</span>:</span> <span class="inlinecode"><span class="id" type="var">COIND</span></span> <span class="inlinecode"><span class="id" type="var">P</span></span>
    instead of being just <span class="inlinecode"><span class="id" type="var">IH</span>:</span> <span class="inlinecode"><span class="id" type="var">P</span></span>. This helps other tactics
    clearing the coinduction hypothesis using <span class="inlinecode"><span class="id" type="var">clear_coind</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Definition</span> <span class="id" type="var">COIND</span> (<span class="id" type="var">P</span>:<span class="id" type="keyword">Prop</span>) := <span class="id" type="var">P</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cofixs" <span class="id" type="var">ident</span>(<span class="id" type="var">IH</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cofix</span> <span class="id" type="var">IH</span>;<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">IH</span> <span class="id" type="keyword">with</span> ?<span class="id" type="var">P</span> ⇒ <span class="id" type="var">change</span> <span class="id" type="var">P</span> <span class="id" type="keyword">with</span> (<span class="id" type="var">COIND</span> <span class="id" type="var">P</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">IH</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
Tactic <span class="inlinecode"><span class="id" type="var">clear_coind</span></span> clears all the coinduction hypotheses,
    assuming that they have been tagged 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">clear_coind</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: <span class="id" type="var">COIND</span> <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
Tactic <span class="inlinecode"><span class="id" type="var">abstracts</span></span> <span class="inlinecode"><span class="id" type="var">tac</span></span> is like <span class="inlinecode"><span class="id" type="var">abstract</span></span> <span class="inlinecode"><span class="id" type="var">tac</span></span> except that
    it clears the coinduction hypotheses so that the productivity
    check will be happy. For example, one can use <span class="inlinecode"><span class="id" type="var">abstracts</span></span> <span class="inlinecode"><span class="id" type="tactic">omega</span></span>
    to obtain the same behavior as <span class="inlinecode"><span class="id" type="tactic">omega</span></span> but with an auxiliary
    lemma being generated. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "abstracts" <span class="id" type="var">tactic</span>(<span class="id" type="var">tac</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clear_coind</span>; <span class="id" type="var">tac</span>.<br/>
</div>

<div class="doc">
<a name="lab505"></a><h1 class="section">Decidable Equality</h1>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">decides_equality</span></span> is the same as <span class="inlinecode"><span class="id" type="var">decide</span></span> <span class="inlinecode"><span class="id" type="var">equality</span></span> excepts that it
    is able to unfold definitions at head of the current goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">decides_equality_tactic</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="var">decide</span> <span class="id" type="var">equality</span> | <span class="id" type="tactic">progress</span>(<span class="id" type="var">unfolds</span>); <span class="id" type="var">decides_equality_tactic</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "decides_equality" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">decides_equality_tactic</span>.<br/>
</div>

<div class="doc">
<a name="lab506"></a><h1 class="section">Equivalence</h1>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">iff</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> can be used to prove an equivalence <span class="inlinecode"><span class="id" type="var">P</span></span> <span class="inlinecode">↔</span> <span class="inlinecode"><span class="id" type="var">Q</span></span> and name <span class="inlinecode"><span class="id" type="var">H</span></span>
    the hypothesis obtained in each case. The syntaxes <span class="inlinecode"><span class="id" type="var">iff</span></span> and <span class="inlinecode"><span class="id" type="var">iff</span></span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">H<sub>2</sub></span></span>
    are also available to specify zero or two names. The tactic <span class="inlinecode"><span class="id" type="var">iff</span></span> <span class="inlinecode">&lt;-</span> <span class="inlinecode"><span class="id" type="var">H</span></span>
    swaps the two subgoals, i.e. produces (Q <span class="nowrap"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>-</span></span>&gt;</span></span> P) as first subgoal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Lemma</span> <span class="id" type="var">iff_intro_swap</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">P</span> <span class="id" type="var">Q</span> : <span class="id" type="keyword">Prop</span>),<br/>
&nbsp;&nbsp;(<span class="id" type="var">Q</span> → <span class="id" type="var">P</span>) → (<span class="id" type="var">P</span> → <span class="id" type="var">Q</span>) → (<span class="id" type="var">P</span> ↔ <span class="id" type="var">Q</span>).<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>. <span class="id" type="tactic">intuition</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "iff" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">split</span>; [ <span class="id" type="tactic">intros</span> <span class="id" type="var">H<sub>1</sub></span> | <span class="id" type="tactic">intros</span> <span class="id" type="var">H<sub>2</sub></span> ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "iff" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">iff</span> <span class="id" type="var">H</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "iff" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "H" <span class="id" type="keyword">in</span> <span class="id" type="var">iff</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "&lt;-" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">iff_intro_swap</span>; [ <span class="id" type="tactic">intros</span> <span class="id" type="var">H<sub>1</sub></span> | <span class="id" type="tactic">intros</span> <span class="id" type="var">H<sub>2</sub></span> ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "&lt;-" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">iff</span> &lt;- <span class="id" type="var">H</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "&lt;-" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "H" <span class="id" type="keyword">in</span> <span class="id" type="var">iff</span> &lt;- <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<a name="lab507"></a><h1 class="section">N-ary Conjunctions and Disjunctions</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
N-ary Conjunctions Splitting in Goals 
<div class="paragraph"> </div>

 Underlying implementation of <span class="inlinecode"><span class="id" type="var">splits</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">splits_tactic</span> <span class="id" type="var">N</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">O</span> ⇒ <span class="id" type="tactic">fail</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">S</span> <span class="id" type="var">O</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">S</span> ?<span class="id" type="var">N'</span> ⇒ <span class="id" type="tactic">split</span>; [| <span class="id" type="var">splits_tactic</span> <span class="id" type="var">N'</span>]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unfold_goal_until_conjunction</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">progress</span>(<span class="id" type="var">unfolds</span>); <span class="id" type="var">unfold_goal_until_conjunction</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_term_conjunction_arity</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(8)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(7)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(6)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(5)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(4)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(3)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(2)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> → ?<span class="id" type="var">T'</span> ⇒ <span class="id" type="var">get_term_conjunction_arity</span> <span class="id" type="var">T'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">P</span> := <span class="id" type="var">get_head</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T'</span> := <span class="id" type="var">eval</span> <span class="id" type="tactic">unfold</span> <span class="id" type="var">P</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T'</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">T</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">get_term_conjunction_arity</span> <span class="id" type="var">T'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;warning&nbsp;this&nbsp;can&nbsp;loop...&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_goal_conjunction_arity</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">T</span> ⇒ <span class="id" type="var">get_term_conjunction_arity</span> <span class="id" type="var">T</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">splits</span></span> applies to a goal of the form <span class="inlinecode">(<span class="id" type="var">T<sub>1</sub></span></span> <span class="inlinecode">∧</span> <span class="inlinecode">..</span> <span class="inlinecode">∧</span> <span class="inlinecode"><span class="id" type="var">TN</span>)</span> and
    destruct it into <span class="inlinecode"><span class="id" type="var">N</span></span> subgoals <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span></span> .. <span class="inlinecode"><span class="id" type="var">TN</span></span>. If the goal is not a
    conjunction, then it unfolds the head definition. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "splits" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfold_goal_until_conjunction</span>;<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">get_goal_conjunction_arity</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">splits_tactic</span> <span class="id" type="var">N</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">splits</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> is similar to <span class="inlinecode"><span class="id" type="var">splits</span></span>, except that it will unfold as many
    definitions as necessary to obtain an <span class="inlinecode"><span class="id" type="var">N</span></span>-ary conjunction. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "splits" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">splits_tactic</span> <span class="id" type="var">N</span>.<br/>
</div>

<div class="doc">
N-ary Conjunctions Deconstruction 
<div class="paragraph"> </div>

 Underlying implementation of <span class="inlinecode"><span class="id" type="var">destructs</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">destructs_conjunction_tactic</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 2 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? ?]<br/>
&nbsp;&nbsp;| 3 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? [? ?]]
  | 4 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? [? [? ?]]]
  | 5 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? [? [? [? ?]]]]
  | 6 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? [? [? [? [? ?]]]]]
  | 7 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? [? [? [? [? [? ?]]]]]]
  <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">destructs</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> allows destructing a term <span class="inlinecode"><span class="id" type="var">T</span></span> which is a N-ary
    conjunction. It is equivalent to <span class="inlinecode"><span class="id" type="tactic">destruct</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode">(<span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">HN</span>)</span>,
    except that it does not require to manually specify N different
    names. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "destructs" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">TT</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">get_term_conjunction_arity</span> <span class="id" type="var">TT</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">destructs_conjunction_tactic</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">destructs</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> is equivalent to <span class="inlinecode"><span class="id" type="tactic">destruct</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode">(<span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">HN</span>)</span>,
    except that it does not require to manually specify N different
    names. Remark that it is not restricted to N-ary conjunctions. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "destructs" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">destructs_conjunction_tactic</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
Proving goals which are N-ary disjunctions 
<div class="paragraph"> </div>

 Underlying implementation of <span class="inlinecode"><span class="id" type="var">branch</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">branch_tactic</span> <span class="id" type="var">K</span> <span class="id" type="var">N</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">constr</span>:((<span class="id" type="var">K</span>,<span class="id" type="var">N</span>)) <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">_</span>,0) ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;| (0,_) ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;| (1,1) ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| (1,_) ⇒ <span class="id" type="var">left</span><br/>
&nbsp;&nbsp;| (<span class="id" type="var">S</span> ?<span class="id" type="var">K'</span>, <span class="id" type="var">S</span> ?<span class="id" type="var">N'</span>) ⇒ <span class="id" type="var">right</span>; <span class="id" type="var">branch_tactic</span> <span class="id" type="var">K'</span> <span class="id" type="var">N'</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unfold_goal_until_disjunction</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| &#x22A2; <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">progress</span>(<span class="id" type="var">unfolds</span>); <span class="id" type="var">unfold_goal_until_disjunction</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_term_disjunction_arity</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(8)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(7)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(6)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(5)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(4)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(3)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(2)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> → ?<span class="id" type="var">T'</span> ⇒ <span class="id" type="var">get_term_disjunction_arity</span> <span class="id" type="var">T'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">P</span> := <span class="id" type="var">get_head</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T'</span> := <span class="id" type="var">eval</span> <span class="id" type="tactic">unfold</span> <span class="id" type="var">P</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T'</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">T</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">get_term_disjunction_arity</span> <span class="id" type="var">T'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_goal_disjunction_arity</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">T</span> ⇒ <span class="id" type="var">get_term_disjunction_arity</span> <span class="id" type="var">T</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">branch</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> applies to a goal of the form
    <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span></span> <span class="inlinecode">∨</span> <span class="inlinecode">...</span> <span class="inlinecode">∨</span> <span class="inlinecode"><span class="id" type="var">PK</span></span> <span class="inlinecode">∨</span> <span class="inlinecode">...</span> <span class="inlinecode">∨</span> <span class="inlinecode"><span class="id" type="var">PN</span></span> and leaves the goal <span class="inlinecode"><span class="id" type="var">PK</span></span>.
    It only able to unfold the head definition (if there is one),
    but for more complex unfolding one should use the tactic
    <span class="inlinecode"><span class="id" type="var">branch</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="var">of</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "branch" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">K</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">K</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">unfold_goal_until_disjunction</span>;<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">get_goal_disjunction_arity</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">branch_tactic</span> <span class="id" type="var">K</span> <span class="id" type="var">N</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">branch</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode"><span class="id" type="var">of</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> is similar to <span class="inlinecode"><span class="id" type="var">branch</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> except that the
    arity of the disjunction <span class="inlinecode"><span class="id" type="var">N</span></span> is given manually, and so this
    version of the tactic is able to unfold definitions.
    In other words, applies to a goal of the form
    <span class="inlinecode"><span class="id" type="var">P<sub>1</sub></span></span> <span class="inlinecode">∨</span> <span class="inlinecode">...</span> <span class="inlinecode">∨</span> <span class="inlinecode"><span class="id" type="var">PK</span></span> <span class="inlinecode">∨</span> <span class="inlinecode">...</span> <span class="inlinecode">∨</span> <span class="inlinecode"><span class="id" type="var">PN</span></span> and leaves the goal <span class="inlinecode"><span class="id" type="var">PK</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "branch" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "of" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">K</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">K</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">branch_tactic</span> <span class="id" type="var">K</span> <span class="id" type="var">N</span>.<br/>
</div>

<div class="doc">
N-ary Disjunction Deconstruction 
<div class="paragraph"> </div>

 Underlying implementation of <span class="inlinecode"><span class="id" type="var">branches</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">destructs_disjunction_tactic</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 2 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? | ?]<br/>
&nbsp;&nbsp;| 3 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? | [? | ?]]
  | 4 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? | [? | [? | ?]]]
  | 5 ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">T</span> <span class="id" type="keyword">as</span> [? | [? | [? | [? | ?]]]]
  <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">branches</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> allows destructing a term <span class="inlinecode"><span class="id" type="var">T</span></span> which is a N-ary
    disjunction. It is equivalent to <span class="inlinecode"><span class="id" type="tactic">destruct</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode"><span class="id" type="keyword">as</span></span> <span class="inlinecode">[</span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode">|</span> <span class="inlinecode">..</span> <span class="inlinecode">|</span> <span class="inlinecode"><span class="id" type="var">HN</span></span> <span class="inlinecode">]</span> <span class="inlinecode"></span>,
    and produces <span class="inlinecode"><span class="id" type="var">N</span></span> subgoals corresponding to the <span class="inlinecode"><span class="id" type="var">N</span></span> possible cases. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "branches" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">TT</span> := <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">get_term_disjunction_arity</span> <span class="id" type="var">TT</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">destructs_disjunction_tactic</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">branches</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> is the same as <span class="inlinecode"><span class="id" type="var">branches</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> except that the arity is
    forced to <span class="inlinecode"><span class="id" type="var">N</span></span>. This version is useful to unfold definitions
    on the fly. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "branches" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">destructs_disjunction_tactic</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">branches</span></span> automatically finds a hypothesis <span class="inlinecode"><span class="id" type="var">h</span></span> that is a disjunction
    and destructs it. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "branches" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">h</span>: <span class="id" type="var">_</span> ∨ <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">branches</span> <span class="id" type="var">h</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;----------------------------------------------------------------------&nbsp;*)</span><br/>
</div>

<div class="doc">
N-ary Existentials 
</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;Underlying&nbsp;implementation&nbsp;of&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span>.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_term_existential_arity</span> <span class="id" type="var">T</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> <span class="id" type="var">x<sub>6</sub></span> <span class="id" type="var">x<sub>7</sub></span> <span class="id" type="var">x<sub>8</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(8)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> <span class="id" type="var">x<sub>6</sub></span> <span class="id" type="var">x<sub>7</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(7)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span> <span class="id" type="var">x<sub>6</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(6)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span> <span class="id" type="var">x<sub>5</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(5)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span> <span class="id" type="var">x<sub>4</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(4)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span> <span class="id" type="var">x<sub>3</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(3)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span> <span class="id" type="var">x<sub>2</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(2)<br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span><span class="id" type="var">x<sub>1</sub></span>, <span class="id" type="var">_</span> ⇒ <span class="id" type="var">constr</span>:(1)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> → ?<span class="id" type="var">T'</span> ⇒ <span class="id" type="var">get_term_existential_arity</span> <span class="id" type="var">T'</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="keyword">let</span> <span class="id" type="var">P</span> := <span class="id" type="var">get_head</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T'</span> := <span class="id" type="var">eval</span> <span class="id" type="tactic">unfold</span> <span class="id" type="var">P</span> <span class="id" type="keyword">in</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T'</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">T</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">get_term_existential_arity</span> <span class="id" type="var">T'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">get_goal_existential_arity</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">T</span> ⇒ <span class="id" type="var">get_term_existential_arity</span> <span class="id" type="var">T</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">TN</span></span> is a shorthand for <span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span>;</span> <span class="inlinecode">...;</span> <span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">TN</span></span>.
    It is intended to prove goals of the form <span class="inlinecode"><span class="id" type="var">exist</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">XN</span>,</span> <span class="inlinecode"><span class="id" type="var">P</span></span>.
    If an argument provided is <span class="inlinecode"><span class="id" type="var">__</span></span> (double underscore), then an
    evar is introduced. <span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">TN</span></span> <span class="inlinecode"><span class="id" type="var">___</span></span> is equivalent to
    <span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">TN</span></span> <span class="inlinecode"><span class="id" type="var">__</span></span> <span class="inlinecode"><span class="id" type="var">__</span></span> <span class="inlinecode"><span class="id" type="var">__</span></span> with as many <span class="inlinecode"><span class="id" type="var">__</span></span> as possible. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "exists_original" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T<sub>1</sub></span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_wild</span> ⇒ <span class="id" type="var">esplit</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">ltac_wilds</span> ⇒ <span class="id" type="tactic">repeat</span> <span class="id" type="var">esplit</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>2</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>2</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>3</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>2</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>3</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>4</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>2</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>3</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>4</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>5</sub></span>; <span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>6</sub></span>.<br/>
</div>

<div class="doc">
For compatibility with Coq syntax, <span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">T<sub>1</sub></span>,</span> <span class="inlinecode">..,</span> <span class="inlinecode"><span class="id" type="var">TN</span></span> is also provided. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span> <span class="id" type="var">T<sub>6</sub></span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;The&nbsp;tactic&nbsp;<span class="inlinecode"><span class="id" type="var">exists___</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span>&nbsp;is&nbsp;short&nbsp;for&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">__</span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">__</span></span><br/>
&nbsp;&nbsp;&nbsp;with&nbsp;<span class="inlinecode"><span class="id" type="var">N</span></span>&nbsp;double-underscores.&nbsp;The&nbsp;tactic&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span>&nbsp;is&nbsp;equivalent<br/>
&nbsp;&nbsp;&nbsp;to&nbsp;calling&nbsp;<span class="inlinecode"><span class="id" type="var">exists___</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span>,&nbsp;where&nbsp;the&nbsp;value&nbsp;of&nbsp;<span class="inlinecode"><span class="id" type="var">N</span></span>&nbsp;is&nbsp;obtained<br/>
&nbsp;&nbsp;&nbsp;by&nbsp;counting&nbsp;the&nbsp;number&nbsp;of&nbsp;existentials&nbsp;syntactically&nbsp;present<br/>
&nbsp;&nbsp;&nbsp;at&nbsp;the&nbsp;head&nbsp;of&nbsp;the&nbsp;goal.&nbsp;The&nbsp;behaviour&nbsp;of&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span>&nbsp;differs<br/>
&nbsp;&nbsp;&nbsp;from&nbsp;that&nbsp;of&nbsp;<span class="inlinecode"><span style='font-size:120%;'>&exist;</span></span> <span class="inlinecode"><span class="id" type="var">___</span></span>&nbsp;is&nbsp;the&nbsp;case&nbsp;where&nbsp;the&nbsp;goal&nbsp;is&nbsp;a<br/>
&nbsp;&nbsp;&nbsp;definition&nbsp;which&nbsp;yields&nbsp;an&nbsp;existential&nbsp;only&nbsp;after&nbsp;unfolding.&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "exists___" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">aux</span> <span class="id" type="var">N</span> :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| 0 ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">S</span> ?<span class="id" type="var">N'</span> ⇒ <span class="id" type="var">esplit</span>; <span class="id" type="var">aux</span> <span class="id" type="var">N'</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">in</span> <span class="id" type="var">aux</span> <span class="id" type="var">N</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;deprecated&nbsp;*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "exists___" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">N</span> := <span class="id" type="var">get_goal_existential_arity</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">exists___</span> <span class="id" type="var">N</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;does&nbsp;not&nbsp;seem&nbsp;to&nbsp;work&nbsp;*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">exists___</span>.<br/><hr class='doublespaceincode'/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;<span class="inlinecode"><span class="id" type="var">exists_all</span></span>&nbsp;is&nbsp;the&nbsp;new&nbsp;syntax&nbsp;for&nbsp;<span class="inlinecode"><span class="id" type="var">exists___</span></span>&nbsp;*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "exists_all" := <span class="id" type="var">exists___</span>.<br/>
</div>

<div class="doc">
Existentials and conjunctions in hypotheses 
<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">unpack</span></span> or <span class="inlinecode"><span class="id" type="var">unpack</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> destructs conjunctions and existentials in
    all or one hypothesis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unpack_core</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">H</span>: <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">H</span>: <span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">varname</span>: <span class="id" type="var">_</span>), <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;kludge&nbsp;to&nbsp;preserve&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;quantified&nbsp;variable&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">name</span> := <span class="id" type="tactic">fresh</span> <span class="id" type="var">varname</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">name</span> ?]<br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">unpack_hypothesis</span> <span class="id" type="var">H</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">H</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ∧ <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">h<sub>1</sub></span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">h<sub>2</sub></span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> [ <span class="id" type="var">h<sub>1</sub></span> <span class="id" type="var">h<sub>2</sub></span> ];<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">unpack_hypothesis</span> <span class="id" type="var">h<sub>1</sub></span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">unpack_hypothesis</span> <span class="id" type="var">h<sub>2</sub></span><br/>
&nbsp;&nbsp;| <span style='font-size:120%;'>&exist;</span>(<span class="id" type="var">varname</span>: <span class="id" type="var">_</span>), <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;kludge&nbsp;to&nbsp;preserve&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;quantified&nbsp;variable&nbsp;*)</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">name</span> := <span class="id" type="tactic">fresh</span> <span class="id" type="var">varname</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">body</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> [<span class="id" type="var">name</span> <span class="id" type="var">body</span>];<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">unpack_hypothesis</span> <span class="id" type="var">body</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "unpack" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unpack_core</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unpack" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unpack_hypothesis</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<a name="lab508"></a><h1 class="section">Tactics to Prove Typeclass Instances</h1>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">typeclass</span></span> is an automation tactic specialized for finding
    typeclass instances. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "typeclass" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">go</span> <span class="id" type="var">_</span> := <span class="id" type="tactic">eauto</span> <span class="id" type="keyword">with</span> <span class="id" type="var">typeclass_instances</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">solve</span> [ <span class="id" type="var">go</span> <span class="id" type="var">tt</span> | <span class="id" type="var">constructor</span>; <span class="id" type="var">go</span> <span class="id" type="var">tt</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">solve_typeclass</span></span> is a simpler version of <span class="inlinecode"><span class="id" type="var">typeclass</span></span>, to use
    in hint tactics for resolving instances 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "solve_typeclass" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">solve</span> [ <span class="id" type="tactic">eauto</span> <span class="id" type="keyword">with</span> <span class="id" type="var">typeclass_instances</span> ].<br/>
</div>

<div class="doc">
<a name="lab509"></a><h1 class="section">Tactics to Invoke Automation</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab510"></a><h2 class="section">Definitions for Parsing Compatibility</h2>

</div>
<div class="code code-space">

<br/>
<span class="id" type="keyword">Tactic Notation</span> "f_equal" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">f_equal</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "constructor" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">constructor</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simple" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "split" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">split</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "right" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">right</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "left" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">left</span>.<br/>
</div>

<div class="doc">
<a name="lab511"></a><h2 class="section"><span class="inlinecode"><span class="id" type="var">hint</span></span> to Add Hints Local to a Lemma</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">hint</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> adds <span class="inlinecode"><span class="id" type="var">E</span></span> as an hypothesis so that automation can use it.
    Syntax <span class="inlinecode"><span class="id" type="var">hint</span></span> <span class="inlinecode"><span class="id" type="var">E<sub>1</sub></span>,..,<span class="id" type="var">EN</span></span> is available 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "hint" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "Hint" <span class="id" type="keyword">in</span> <span class="id" type="var">lets</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "hint" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hint</span> <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">hint</span> <span class="id" type="var">E<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "hint" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hint</span> <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">hint</span> <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">hint</span>(<span class="id" type="var">E<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "hint" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hint</span> <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">hint</span> <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">hint</span>(<span class="id" type="var">E<sub>3</sub></span>); <span class="id" type="var">hint</span>(<span class="id" type="var">E<sub>4</sub></span> ).<br/>
</div>

<div class="doc">
<a name="lab512"></a><h2 class="section"><span class="inlinecode"><span class="id" type="var">jauto</span></span>, a New Automation Tactic</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">jauto</span></span> is better at <span class="inlinecode"><span class="id" type="tactic">intuition</span></span> <span class="inlinecode"><span class="id" type="tactic">eauto</span></span> because it can open existentials
    from the context. In the same time, <span class="inlinecode"><span class="id" type="var">jauto</span></span> can be faster than
    <span class="inlinecode"><span class="id" type="tactic">intuition</span></span> <span class="inlinecode"><span class="id" type="tactic">eauto</span></span> because it does not destruct disjunctions from the
    context. The strategy of <span class="inlinecode"><span class="id" type="var">jauto</span></span> can be summarized as follows:

<div class="paragraph"> </div>

<ul class="doclist">
<li> open all the existentials and conjunctions from the context

</li>
<li> call esplit and split on the existentials and conjunctions in the goal

</li>
<li> call eauto. 
</li>
</ul>

</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "jauto" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="var">jauto_set</span>; <span class="id" type="tactic">eauto</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "jauto_fast" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="tactic">auto</span> | <span class="id" type="tactic">eauto</span> | <span class="id" type="var">jauto</span> ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">iauto</span></span> is a shorthand for <span class="inlinecode"><span class="id" type="tactic">intuition</span></span> <span class="inlinecode"><span class="id" type="tactic">eauto</span></span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "iauto" := <span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [<span class="id" type="tactic">intuition</span> <span class="id" type="tactic">eauto</span>].<br/>
</div>

<div class="doc">
<a name="lab513"></a><h2 class="section">Definitions of Automation Tactics</h2>

<div class="paragraph"> </div>

 The two following tactics defined the default behaviour of
    "light automation" and "strong automation". These tactics
    may be redefined at any time using the syntax <span class="inlinecode"><span class="id" type="keyword">Ltac</span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span style='font-size:85%;'><span style='vertical-align:5%;'><span style='letter-spacing:-.2em;'>:</span>:</span>=</span></span> <span class="inlinecode">..</span>. 
<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">auto_tilde</span></span> is the tactic which will be called each time a symbol
    <span class="inlinecode">¬</span> is used after a tactic. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">auto_tilde_default</span> := <span class="id" type="tactic">auto</span>.<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">auto_tilde</span> := <span class="id" type="var">auto_tilde_default</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">auto_star</span></span> is the tactic which will be called each time a symbol
    <span class="inlinecode">*</span> is used after a tactic. 
</div>
<div class="code code-tight">

<span class="comment">(*&nbsp;SPECIAL&nbsp;VERSION&nbsp;FOR&nbsp;SF*)</span><br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">auto_star_default</span> := <span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="var">jauto</span> ].<br/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">auto_star</span> := <span class="id" type="var">auto_star_default</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">autos</span>¬</span> is a notation for tactic <span class="inlinecode"><span class="id" type="var">auto_tilde</span></span>. It may be followed
    by lemmas (or proofs terms) which auto will be able to use
    for solving the goal.  <span class="inlinecode"><span class="id" type="var">autos</span></span> is an alias for <span class="inlinecode"><span class="id" type="var">autos</span>¬</span> 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "autos" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">autos</span>*</span> is a notation for tactic <span class="inlinecode"><span class="id" type="var">auto_star</span></span>. It may be followed
    by lemmas (or proofs terms) which auto will be able to use
    for solving the goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "autos" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "autos" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>1</sub></span>; <span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>2</sub></span>; <span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">auto_false</span></span> is a version of <span class="inlinecode"><span class="id" type="tactic">auto</span></span> able to spot some contradictions.
    There is an ad-hoc support for goals in <span class="inlinecode">↔</span>: split is called first.
    <span class="inlinecode"><span class="id" type="var">auto_false</span>¬</span> and <span class="inlinecode"><span class="id" type="var">auto_false</span>*</span> are also available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">auto_false_base</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">intros_all</span>; <span class="id" type="tactic">try</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; <span class="id" type="var">_</span> ↔ <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">split</span> <span class="id" type="keyword">end</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">solve</span> [ <span class="id" type="var">cont</span> <span class="id" type="var">tt</span> | <span class="id" type="var">intros_all</span>; <span class="id" type="var">false</span>; <span class="id" type="var">cont</span> <span class="id" type="var">tt</span> ] ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "auto_false" :=<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">auto_false_base</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">tt</span> ⇒ <span class="id" type="tactic">auto</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "auto_false" "¬" :=<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">auto_false_base</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">tt</span> ⇒ <span class="id" type="var">auto_tilde</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "auto_false" "*" :=<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">auto_false_base</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">tt</span> ⇒ <span class="id" type="var">auto_star</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "dauto" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">dintuition</span> <span class="id" type="tactic">eauto</span>.<br/>
</div>

<div class="doc">
<a name="lab514"></a><h2 class="section">Parsing for Light Automation</h2>

<div class="paragraph"> </div>

 Any tactic followed by the symbol <span class="inlinecode">¬</span> will have <span class="inlinecode"><span class="id" type="var">auto_tilde</span></span> called
    on all of its subgoals. Three exceptions:

<div class="paragraph"> </div>

<ul class="doclist">
<li> <span class="inlinecode"><span class="id" type="var">cuts</span></span> and <span class="inlinecode"><span class="id" type="var">asserts</span></span> only call <span class="inlinecode"><span class="id" type="tactic">auto</span></span> on their first subgoal,

</li>
<li> <span class="inlinecode"><span class="id" type="tactic">apply</span>¬</span> relies on <span class="inlinecode"><span class="id" type="var">sapply</span></span> rather than <span class="inlinecode"><span class="id" type="tactic">apply</span></span>,

</li>
<li> <span class="inlinecode"><span class="id" type="var">tryfalse</span>¬</span> is defined as <span class="inlinecode"><span class="id" type="var">tryfalse</span></span> <span class="inlinecode"><span class="id" type="tactic">by</span></span> <span class="inlinecode"><span class="id" type="var">auto_tilde</span></span>.

</li>
</ul>

<div class="paragraph"> </div>

   Some builtin tactics are not defined using tactic notations
   and thus cannot be extended, e.g., <span class="inlinecode"><span class="id" type="tactic">simpl</span></span> and <span class="inlinecode"><span class="id" type="tactic">unfold</span></span>.
   For these, notation such as <span class="inlinecode"><span class="id" type="tactic">simpl</span>¬</span> will not be available. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "equates" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span> <span class="id" type="var">n<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span> <span class="id" type="var">n<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "apply" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "f_equal" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">f_equal</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "induction" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inversion" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "split" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">split</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "subst" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">subst</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "right" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">right</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "left" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">left</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "constructor" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">constructor</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "constructors" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">constructors</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "false" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false_then</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">auto_tilde</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>¬(&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>¬(&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>¬(&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span> <span class="id" type="var">E<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>¬(&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span> <span class="id" type="var">E<sub>3</sub></span> <span class="id" type="var">E<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "tryfalse" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="var">false</span>¬].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; [ <span class="id" type="var">auto_tilde</span> | <span class="id" type="var">idtac</span> ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "H" <span class="id" type="keyword">in</span> <span class="id" type="var">asserts</span>¬<span class="id" type="var">H</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; [ <span class="id" type="var">auto_tilde</span> | <span class="id" type="var">idtac</span> ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span>: <span class="id" type="var">E</span>; [ <span class="id" type="var">auto_tilde</span> | <span class="id" type="var">idtac</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>. <span class="comment">(*todo?*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fapply" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapply</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "sapply" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "logic" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">logic_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">auto_tilde</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "intros_all" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">intros_all</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>, <span class="id" type="var">F<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>, <span class="id" type="var">F<sub>2</sub></span>, <span class="id" type="var">F<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>, <span class="id" type="var">F<sub>2</sub></span>, <span class="id" type="var">F<sub>3</sub></span>, <span class="id" type="var">F<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "simple" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simple" "¬" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simpls" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">simpls</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "hnfs" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hnfs</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "hnfs" "¬" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "substs" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">substs</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "intro_hyp" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">subst_hyp</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "intro_subst" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">intro_subst</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "subst_eq" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">subst_eq</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "¬" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "erewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">erewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fequal" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fequal</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "fequals" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fequals</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "pi_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pi_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "pi_rewrite" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pi_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "invert" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">E</span>) "as" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "injects" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">injects</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inversions" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inversions</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_if</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "case_ifs" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_ifs</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "¬" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "¬" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "¬" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_head_match" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_head_match</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases'" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases'</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases'" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases'</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if'" "¬" "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if'</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if'" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if'</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "decides_equality" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">decides_equality</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">iff</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "¬" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">iff</span> <span class="id" type="var">I</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "splits" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">splits</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "splits" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">splits</span> <span class="id" type="var">N</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destructs" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destructs</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destructs" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destructs</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "branch" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branch</span> <span class="id" type="var">N</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "branch" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "of" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branch</span> <span class="id" type="var">K</span> <span class="id" type="var">of</span> <span class="id" type="var">N</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "branches" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branches</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "branches" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branches</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "branches" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branches</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists___" "¬" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">exists___</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span> <span class="id" type="var">T<sub>6</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "¬" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span> <span class="id" type="var">T<sub>6</sub></span>; <span class="id" type="var">auto_tilde</span>.<br/>
</div>

<div class="doc">
<a name="lab515"></a><h2 class="section">Parsing for Strong Automation</h2>

<div class="paragraph"> </div>

 Any tactic followed by the symbol <span class="inlinecode">*</span> will have <span class="inlinecode"><span class="id" type="tactic">auto</span>*</span> called
    on all of its subgoals. The exceptions to these rules are the
    same as for light automation.

<div class="paragraph"> </div>

    Exception: use <span class="inlinecode"><span class="id" type="var">subs</span>*</span> instead of <span class="inlinecode"><span class="id" type="tactic">subst</span>*</span> if you
    import the library <span class="inlinecode"><span class="id" type="var">Coq.Classes.Equivalence</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "equates" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "equates" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">equates</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span> <span class="id" type="var">n<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys_eq" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">n<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys_eq</span> <span class="id" type="var">H</span> <span class="id" type="var">n<sub>1</sub></span> <span class="id" type="var">n<sub>2</sub></span> <span class="id" type="var">n<sub>3</sub></span> <span class="id" type="var">n<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "apply" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destruct" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) "as" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">destruct</span> <span class="id" type="var">H</span> <span class="id" type="keyword">as</span> <span class="id" type="var">I</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "f_equal" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">f_equal</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "induction" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">induction</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inversion" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">inversion</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "split" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">split</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "subs" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">subst</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "subst" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">subst</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "right" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">right</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "left" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">left</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "constructor" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">constructor</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "constructors" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">constructors</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "false" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false_then</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">auto_star</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>* (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>* (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>* (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span> <span class="id" type="var">E<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "false" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">false</span>* (&gt;&gt; <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">E<sub>1</sub></span> <span class="id" type="var">E<sub>2</sub></span> <span class="id" type="var">E<sub>3</sub></span> <span class="id" type="var">E<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "tryfalse" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="var">solve</span> [ <span class="id" type="var">false</span>* ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; [ <span class="id" type="var">auto_star</span> | <span class="id" type="var">idtac</span> ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "H" <span class="id" type="keyword">in</span> <span class="id" type="var">asserts</span>* <span class="id" type="var">H</span>: <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">H</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span> <span class="id" type="var">H</span>: <span class="id" type="var">E</span>; [ <span class="id" type="var">auto_star</span> | <span class="id" type="var">idtac</span> ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span>: <span class="id" type="var">E</span>; [ <span class="id" type="var">auto_star</span> | <span class="id" type="var">idtac</span> ].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "lets" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">lets</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span> <span class="id" type="var">I</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "forwards" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards</span>: <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>. <span class="comment">(*todo?*)</span><br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "applys" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E<sub>0</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">applys</span> <span class="id" type="var">E<sub>0</sub></span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" "¬" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "specializes" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>4</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">A<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">specializes</span> <span class="id" type="var">H</span> <span class="id" type="var">A<sub>1</sub></span> <span class="id" type="var">A<sub>2</sub></span> <span class="id" type="var">A<sub>3</sub></span> <span class="id" type="var">A<sub>4</sub></span> <span class="id" type="var">A<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fapply" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fapply</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "sapply" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "logic" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">logic_base</span> <span class="id" type="var">E</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">auto_star</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "intros_all" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">intros_all</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>, <span class="id" type="var">F<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>, <span class="id" type="var">F<sub>2</sub></span>, <span class="id" type="var">F<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "unfolds" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>3</sub></span>) ","<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">F<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">unfolds</span> <span class="id" type="var">F<sub>1</sub></span>, <span class="id" type="var">F<sub>2</sub></span>, <span class="id" type="var">F<sub>3</sub></span>, <span class="id" type="var">F<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "simple" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simple" "*" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">simpl</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "simpls" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">simpls</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "hnfs" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hnfs</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "hnfs" "*" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hnf</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "substs" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">substs</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "intro_hyp" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">subst_hyp</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "intro_subst" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">intro_subst</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "subst_eq" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">subst_eq</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>):=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*":=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>):=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrites" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*":=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrites</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "rewrite_all" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">rewrite_all</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "asserts_rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts_rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> *; <span class="id" type="var">auto_tilde</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> &lt;- <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cuts_rewrite" "*" "&lt;-" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts_rewrite</span> &lt;- <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "erewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">erewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "fequal" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fequal</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "fequals" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">fequals</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "pi_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pi_rewrite</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "pi_rewrite" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">pi_rewrite</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "invert" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">invert</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inverts" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">E</span>) "as" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inverts</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "injects" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">injects</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "inversions" "*" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">inversions</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_if</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "case_ifs" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_ifs</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "case_if" "*" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">case_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if" "*" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
&nbsp;<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_if" "*" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_if</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destruct_head_match" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destruct_head_match</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "cases'" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases'</span> <span class="id" type="var">E</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases'" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases'</span> <span class="id" type="var">E</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if'" "*" "as" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if'</span> <span class="id" type="keyword">as</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "cases_if'" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cases_if'</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "decides_equality" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">decides_equality</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">iff</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "iff" "*" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">iff</span> <span class="id" type="var">I</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "splits" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">splits</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "splits" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">splits</span> <span class="id" type="var">N</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "destructs" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destructs</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "destructs" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">destructs</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "branch" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branch</span> <span class="id" type="var">N</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "branch" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">K</span>) "of" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branch</span> <span class="id" type="var">K</span> <span class="id" type="var">of</span> <span class="id" type="var">N</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "branches" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branches</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "branches" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">branches</span> <span class="id" type="var">N</span> <span class="id" type="var">T</span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists___" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">exists___</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span> <span class="id" type="var">T<sub>6</sub></span>; <span class="id" type="var">auto_star</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <br/>
&nbsp;&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "exists" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>2</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>3</sub></span>) "," <br/>
&nbsp;<span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>4</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>5</sub></span>) ","  <span class="id" type="var">constr</span>(<span class="id" type="var">T<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&exist;</span><span class="id" type="var">T<sub>1</sub></span> <span class="id" type="var">T<sub>2</sub></span> <span class="id" type="var">T<sub>3</sub></span> <span class="id" type="var">T<sub>4</sub></span> <span class="id" type="var">T<sub>5</sub></span> <span class="id" type="var">T<sub>6</sub></span>; <span class="id" type="var">auto_star</span>.<br/>
</div>

<div class="doc">
<a name="lab516"></a><h1 class="section">Tactics to Sort Out the Proof Context</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab517"></a><h2 class="section">Hiding Hypotheses</h2>

</div>
<div class="code code-space">

<br/>
<span class="comment">(*&nbsp;Implementation&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Definition</span> <span class="id" type="var">ltac_something</span> (<span class="id" type="var">P</span>:<span class="id" type="keyword">Type</span>) (<span class="id" type="var">e</span>:<span class="id" type="var">P</span>) := <span class="id" type="var">e</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Notation</span> "'Something'" :=<br/>
&nbsp;&nbsp;(@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">ltac_something_eq</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">e</span>:<span class="id" type="keyword">Type</span>),<br/>
&nbsp;&nbsp;<span class="id" type="var">e</span> = (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">e</span>).<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">ltac_something_hide</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">e</span>:<span class="id" type="keyword">Type</span>),<br/>
&nbsp;&nbsp;<span class="id" type="var">e</span> → (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">e</span>).<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">ltac_something_show</span> : <span style='font-size:120%;'>&forall;</span>(<span class="id" type="var">e</span>:<span class="id" type="keyword">Type</span>),<br/>
&nbsp;&nbsp;(@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">e</span>) → <span class="id" type="var">e</span>.<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>. <span class="id" type="tactic">auto</span>. <span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">hide_def</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> and <span class="inlinecode"><span class="id" type="var">show_def</span></span> <span class="inlinecode"><span class="id" type="var">x</span></span> can be used to hide/show
    the body of the definition <span class="inlinecode"><span class="id" type="var">x</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "hide_def" <span class="id" type="var">hyp</span>(<span class="id" type="var">x</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">x'</span> := <span class="id" type="var">constr</span>:(<span class="id" type="var">x</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">T</span> := <span class="id" type="var">eval</span> <span class="id" type="tactic">unfold</span> <span class="id" type="var">x</span> <span class="id" type="keyword">in</span> <span class="id" type="var">x'</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="var">change</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">T</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">x</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "show_def" <span class="id" type="var">hyp</span>(<span class="id" type="var">x</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">x'</span> := <span class="id" type="var">constr</span>:(<span class="id" type="var">x</span>) <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">U</span> := <span class="id" type="var">eval</span> <span class="id" type="tactic">unfold</span> <span class="id" type="var">x</span> <span class="id" type="keyword">in</span> <span class="id" type="var">x'</span> <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">U</span> <span class="id" type="keyword">with</span> @<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> ?<span class="id" type="var">T</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">change</span> <span class="id" type="var">U</span> <span class="id" type="keyword">with</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span> <span class="id" type="var">x</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">show_def</span></span> unfolds <span class="inlinecode"><span class="id" type="var">Something</span></span> in the goal 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "show_def" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">ltac_something</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_def" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">ltac_something</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_def" "in" "*" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">ltac_something</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">hide_defs</span></span> and <span class="inlinecode"><span class="id" type="var">show_defs</span></span> applies to all definitions 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "hide_defs" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span> := ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| @<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">change</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">T</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "show_defs" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span> := (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> ?<span class="id" type="var">T</span>) &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">change</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">T</span>) <span class="id" type="keyword">with</span> <span class="id" type="var">T</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">hide_hyp</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> replaces the type of <span class="inlinecode"><span class="id" type="var">H</span></span> with the notation <span class="inlinecode"><span class="id" type="var">Something</span></span>
    and <span class="inlinecode"><span class="id" type="var">show_hyp</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> reveals the type of the hypothesis. Note that the
    hidden type of <span class="inlinecode"><span class="id" type="var">H</span></span> remains convertible the real type of <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "show_hyp" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ltac_something_show</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "hide_hyp" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">apply</span> <span class="id" type="var">ltac_something_hide</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">hide_hyps</span></span> and <span class="inlinecode"><span class="id" type="var">show_hyps</span></span> can be used to hide/show all hypotheses
    of type <span class="inlinecode"><span class="id" type="keyword">Prop</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "show_hyps" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">H</span>: @<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">show_hyp</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "hide_hyps" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="keyword">Prop</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| @<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">fail</span> 2<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">hide_hyp</span> <span class="id" type="var">H</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">fail</span> 1<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="keyword">end</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">hide</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> and <span class="inlinecode"><span class="id" type="var">show</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> automatically select between
    <span class="inlinecode"><span class="id" type="var">hide_hyp</span></span> or <span class="inlinecode"><span class="id" type="var">hide_def</span></span>, and <span class="inlinecode"><span class="id" type="var">show_hyp</span></span> or <span class="inlinecode"><span class="id" type="var">show_def</span></span>.
    Similarly <span class="inlinecode"><span class="id" type="var">hide_all</span></span> and <span class="inlinecode"><span class="id" type="var">show_all</span></span> apply to all. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "hide" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [<span class="id" type="var">hide_def</span> <span class="id" type="var">H</span> | <span class="id" type="var">hide_hyp</span> <span class="id" type="var">H</span>].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "show" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">first</span> [<span class="id" type="var">show_def</span> <span class="id" type="var">H</span> | <span class="id" type="var">show_hyp</span> <span class="id" type="var">H</span>].<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "hide_all" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">hide_hyps</span>; <span class="id" type="var">hide_defs</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "show_all" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">ltac_something</span> <span class="id" type="keyword">in</span> *.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">hide_term</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> can be used to hide a term from the goal.
    <span class="inlinecode"><span class="id" type="var">show_term</span></span> or <span class="inlinecode"><span class="id" type="var">show_term</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> can be used to reveal it.
    <span class="inlinecode"><span class="id" type="var">hide_term</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> can be used to specify an hypothesis. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "hide_term" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">change</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">E</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_term" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">change</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">with</span> <span class="id" type="var">E</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_term" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">ltac_something</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "hide_term" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">change</span> <span class="id" type="var">E</span> <span class="id" type="keyword">with</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_term" <span class="id" type="var">constr</span>(<span class="id" type="var">E</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">change</span> (@<span class="id" type="var">ltac_something</span> <span class="id" type="var">_</span> <span class="id" type="var">E</span>) <span class="id" type="keyword">with</span> <span class="id" type="var">E</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_term" "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">ltac_something</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">show_unfold</span></span> <span class="inlinecode"><span class="id" type="var">R</span></span> unfolds the definition of <span class="inlinecode"><span class="id" type="var">R</span></span> and
    reveals the hidden definition of R. &mdash;todo:test,
    and implement using unfold simply 
</div>
<div class="code code-tight">
&nbsp;&nbsp;&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;change&nbsp;"unfolds"&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "show_unfold" <span class="id" type="var">constr</span>(<span class="id" type="var">R<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">R<sub>1</sub></span>; <span class="id" type="var">show_def</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "show_unfold" <span class="id" type="var">constr</span>(<span class="id" type="var">R<sub>1</sub></span>) "," <span class="id" type="var">constr</span>(<span class="id" type="var">R<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">unfold</span> <span class="id" type="var">R<sub>1</sub></span>, <span class="id" type="var">R<sub>2</sub></span>; <span class="id" type="var">show_def</span>.<br/>
</div>

<div class="doc">
<a name="lab518"></a><h2 class="section">Sorting Hypotheses</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">sort</span></span> sorts out hypotheses from the context by moving all the
    propositions (hypotheses of type Prop) to the bottom of the context. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">sort_tactic</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">try</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span> <span class="id" type="keyword">Prop</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">generalizes</span> <span class="id" type="var">H</span>; (<span class="id" type="tactic">try</span> <span class="id" type="var">sort_tactic</span>); <span class="id" type="tactic">intro</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "sort" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">sort_tactic</span>.<br/>
</div>

<div class="doc">
<a name="lab519"></a><h2 class="section">Clearing Hypotheses</h2>

<div class="paragraph"> </div>

 <span class="inlinecode"><span class="id" type="var">clears</span></span> <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span> <span class="inlinecode">...</span> <span class="inlinecode"><span class="id" type="var">XN</span></span> is a variation on <span class="inlinecode"><span class="id" type="tactic">clear</span></span> which clears
    the variables <span class="inlinecode"><span class="id" type="var">X<sub>1</sub></span></span>..<span class="inlinecode"><span class="id" type="var">XN</span></span> as well as all the hypotheses which
    depend on them. Contrary to <span class="inlinecode"><span class="id" type="tactic">clear</span></span>, it never fails. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "clears" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">rec</span> <span class="id" type="var">doit</span> <span class="id" type="var">_</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">H</span>:<span class="id" type="var">context</span>[<span class="id" type="var">X<sub>1</sub></span>] &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">try</span> (<span class="id" type="var">doit</span> <span class="id" type="var">tt</span>)<br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">X<sub>1</sub></span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">in</span> <span class="id" type="var">doit</span> <span class="id" type="var">tt</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>2</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>3</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>4</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>5</sub></span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears" <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>4</sub></span>)<br/>
&nbsp;<span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>5</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">X<sub>6</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears</span> <span class="id" type="var">X<sub>1</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>2</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>3</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>4</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>5</sub></span>; <span class="id" type="var">clears</span> <span class="id" type="var">X<sub>6</sub></span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">clears</span></span> (without any argument) clears all the unused variables
    from the context. In other words, it removes any variable
    which is not a proposition (i.e. not of type Prop) and which
    does not appear in another hypothesis nor in the goal. 
</div>
<div class="code code-tight">
&nbsp;&nbsp;<span class="comment">(*&nbsp;--TODO:&nbsp;rename&nbsp;to&nbsp;clears_var&nbsp;?&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">clears_tactic</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">type</span> <span class="id" type="var">of</span> <span class="id" type="var">T</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="keyword">Prop</span> ⇒ <span class="id" type="var">generalizes</span> <span class="id" type="var">H</span>; (<span class="id" type="tactic">try</span> <span class="id" type="var">clears_tactic</span>); <span class="id" type="tactic">intro</span><br/>
&nbsp;&nbsp;| ?<span class="id" type="var">TT</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span>; (<span class="id" type="tactic">try</span> <span class="id" type="var">clears_tactic</span>)<br/>
&nbsp;&nbsp;| ?<span class="id" type="var">TT</span> ⇒ <span class="id" type="var">generalizes</span> <span class="id" type="var">H</span>; (<span class="id" type="tactic">try</span> <span class="id" type="var">clears_tactic</span>); <span class="id" type="tactic">intro</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "clears" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_tactic</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">clears_all</span></span> clears all the hypotheses from the context
    that can be cleared. It leaves only the hypotheses that
    are mentioned in the goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">clears_or_generalizes_all_core</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">repeat</span> <span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: <span class="id" type="var">_</span> &#x22A2; <span class="id" type="var">_</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">first</span> [ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> | <span class="id" type="var">generalizes</span> <span class="id" type="var">H</span>] <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "clears_all" :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">ltac_mark</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_or_generalizes_all_core</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">intro_until_mark</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">clears_but</span></span> <span class="inlinecode"><span class="id" type="var">H<sub>1</sub></span></span> <span class="inlinecode"><span class="id" type="var">H<sub>2</sub></span></span> <span class="inlinecode">..</span> <span class="inlinecode"><span class="id" type="var">HN</span></span> clears all hypotheses except the
    one that are mentioned and those that cannot be cleared. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Ltac</span> <span class="id" type="var">clears_but_core</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">ltac_mark</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">cont</span> <span class="id" type="var">tt</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_or_generalizes_all_core</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">intro_until_mark</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "clears_but" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears_but" <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>1</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">gen</span> <span class="id" type="var">H<sub>1</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears_but" <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>2</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">gen</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">H<sub>2</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears_but" <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>3</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">gen</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">H<sub>3</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears_but" <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>4</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">gen</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">H<sub>3</sub></span> <span class="id" type="var">H<sub>4</sub></span>).<br/>
<span class="id" type="keyword">Tactic Notation</span> "clears_but" <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>1</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>2</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>3</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>4</sub></span>) <span class="id" type="var">ident</span>(<span class="id" type="var">H<sub>5</sub></span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but_core</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">_</span> ⇒ <span class="id" type="var">gen</span> <span class="id" type="var">H<sub>1</sub></span> <span class="id" type="var">H<sub>2</sub></span> <span class="id" type="var">H<sub>3</sub></span> <span class="id" type="var">H<sub>4</sub></span> <span class="id" type="var">H<sub>5</sub></span>).<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Lemma</span> <span class="id" type="var">demo_clears_all_and_clears_but</span> :<br/>
&nbsp;&nbsp;<span style='font-size:120%;'>&forall;</span><span class="id" type="var">x</span> <span class="id" type="var">y</span>:<span class="id" type="var">nat</span>, <span class="id" type="var">y</span> &lt; 2 → <span class="id" type="var">x</span> = <span class="id" type="var">x</span> → <span class="id" type="var">x</span> ≥ 2 → <span class="id" type="var">x</span> &lt; 3 → <span class="id" type="var">True</span>.<br/>
<span class="id" type="keyword">Proof</span> <span class="id" type="keyword">using</span>.<br/>
&nbsp;&nbsp;<span class="id" type="var">introv</span> <span class="id" type="var">M<sub>1</sub></span> <span class="id" type="var">M<sub>2</sub></span> <span class="id" type="var">M<sub>3</sub></span>. <span class="id" type="var">dup</span> 6.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;<span class="inlinecode"><span class="id" type="var">clears_all</span></span>&nbsp;clears&nbsp;all&nbsp;hypotheses.&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="var">clears_all</span>. <span class="id" type="tactic">auto</span>.<br/>
&nbsp;&nbsp;<span class="comment">(*&nbsp;<span class="inlinecode"><span class="id" type="var">clears_but</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span>&nbsp;clears&nbsp;all&nbsp;but&nbsp;<span class="inlinecode"><span class="id" type="var">H</span></span>&nbsp;*)</span><br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but</span> <span class="id" type="var">M<sub>3</sub></span>. <span class="id" type="tactic">auto</span>.<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but</span> <span class="id" type="var">y</span>. <span class="id" type="tactic">auto</span>.<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but</span> <span class="id" type="var">x</span>. <span class="id" type="tactic">auto</span>.<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but</span> <span class="id" type="var">M<sub>2</sub></span> <span class="id" type="var">M<sub>3</sub></span>. <span class="id" type="tactic">auto</span>.<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_but</span> <span class="id" type="var">x</span> <span class="id" type="var">y</span>. <span class="id" type="tactic">auto</span>.<br/>
<span class="id" type="keyword">Qed</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">clears_last</span></span> clears the last hypothesis in the context.
    <span class="inlinecode"><span class="id" type="var">clears_last</span></span> <span class="inlinecode"><span class="id" type="var">N</span></span> clears the last <span class="inlinecode"><span class="id" type="var">N</span></span> hypotheses in the context. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "clears_last" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> <span class="id" type="var">H</span>: ?<span class="id" type="var">T</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="tactic">clear</span> <span class="id" type="var">H</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">clears_last_base</span> <span class="id" type="var">N</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">number_to_nat</span> <span class="id" type="var">N</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| 0 ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">S</span> ?<span class="id" type="var">p</span> ⇒ <span class="id" type="var">clears_last</span>; <span class="id" type="var">clears_last_base</span> <span class="id" type="var">p</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "clears_last" <span class="id" type="var">constr</span>(<span class="id" type="var">N</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">clears_last_base</span> <span class="id" type="var">N</span>.<br/>
</div>

<div class="doc">
<a name="lab520"></a><h1 class="section">Tactics for Development Purposes</h1>

</div>
<div class="code code-space">

<br/>
</div>

<div class="doc">
<a name="lab521"></a><h2 class="section">Skipping Subgoals</h2>

</div>
<div class="code code-space">

<br/>
<span class="comment">(*&nbsp;SF&nbsp;DOES&nbsp;NOT&nbsp;NEED&nbsp;an&nbsp;alternative&nbsp;implementation&nbsp;of&nbsp;the&nbsp;<span class="inlinecode"><span class="id" type="var">skip</span></span>&nbsp;tactic&nbsp;*)</span><br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "skip" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">admit</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">demo</span></span> is like <span class="inlinecode"><span class="id" type="var">admit</span></span> but it documents the fact that admit is intended 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "demo" :=<br/>
&nbsp;&nbsp;<span class="id" type="var">skip</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">admits</span></span> <span class="inlinecode"><span class="id" type="var">H</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> adds an assumption named <span class="inlinecode"><span class="id" type="var">H</span></span> of type <span class="inlinecode"><span class="id" type="var">T</span></span> to the
    current context, blindly assuming that it is true.
    <span class="inlinecode"><span class="id" type="var">admit</span>:</span> <span class="inlinecode"><span class="id" type="var">T</span></span> is another possible syntax.
    Note that H may be an intro pattern. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "admits" <span class="id" type="var">simple_intropattern</span>(<span class="id" type="var">I</span>) ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">asserts</span> <span class="id" type="var">I</span>: <span class="id" type="var">T</span>; [ <span class="id" type="var">skip</span> | ].<br/>
<span class="id" type="keyword">Tactic Notation</span> "admits" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">H</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">admits</span> <span class="id" type="var">H</span>: <span class="id" type="var">T</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "admits" "¬" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">admits</span>: <span class="id" type="var">T</span>; <span class="id" type="var">auto_tilde</span>.<br/>
<span class="id" type="keyword">Tactic Notation</span> "admits" "*" ":" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">admits</span>: <span class="id" type="var">T</span>; <span class="id" type="var">auto_star</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">admit_cuts</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> simply replaces the current goal with <span class="inlinecode"><span class="id" type="var">T</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "admit_cuts" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="var">cuts</span>: <span class="id" type="var">T</span>; [ <span class="id" type="var">skip</span> | ].<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">admit_goal</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> applies to any goal. It simply assumes
    the current goal to be true. The assumption is named "H".
    It is useful to set up proof by induction or coinduction.
    Syntax <span class="inlinecode"><span class="id" type="var">admit_goal</span></span> is also accepted.
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "admit_goal" <span class="id" type="var">ident</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span> &#x22A2; ?<span class="id" type="var">G</span> ⇒ <span class="id" type="var">admits</span> <span class="id" type="var">H</span>: <span class="id" type="var">G</span> <span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Tactic Notation</span> "admit_goal" :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">IH</span> := <span class="id" type="tactic">fresh</span> "IH" <span class="id" type="keyword">in</span> <span class="id" type="var">admit_goal</span> <span class="id" type="var">IH</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">admit_rewrite</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> can be applied when <span class="inlinecode"><span class="id" type="var">T</span></span> is an equality.
    It blindly assumes this equality to be true, and rewrite it in
    the goal. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "admit_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">M</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">admits</span> <span class="id" type="var">M</span>: <span class="id" type="var">T</span>; <span class="id" type="tactic">rewrite</span> <span class="id" type="var">M</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">M</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">admit_rewrite</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> <span class="inlinecode"><span class="id" type="keyword">in</span></span> <span class="inlinecode"><span class="id" type="var">H</span></span> is similar as <span class="inlinecode"><span class="id" type="var">admit_rewrite</span></span>, except that
    it rewrites in hypothesis <span class="inlinecode"><span class="id" type="var">H</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "admit_rewrite" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) "in" <span class="id" type="var">hyp</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">M</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">admits</span> <span class="id" type="var">M</span>: <span class="id" type="var">T</span>; <span class="id" type="tactic">rewrite</span> <span class="id" type="var">M</span> <span class="id" type="keyword">in</span> <span class="id" type="var">H</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">M</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">admit_rewrites_all</span></span> <span class="inlinecode"><span class="id" type="var">T</span></span> is similar as <span class="inlinecode"><span class="id" type="var">admit_rewrite</span></span>, except that
    it rewrites everywhere (goal and all hypotheses). 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Tactic Notation</span> "admit_rewrite_all" <span class="id" type="var">constr</span>(<span class="id" type="var">T</span>) :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">M</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span> <span class="id" type="var">admits</span> <span class="id" type="var">M</span>: <span class="id" type="var">T</span>; <span class="id" type="var">rewrite_all</span> <span class="id" type="var">M</span>; <span class="id" type="tactic">clear</span> <span class="id" type="var">M</span>.<br/>
</div>

<div class="doc">
<span class="inlinecode"><span class="id" type="var">forwards_nounfold_admit_sides_then</span></span> <span class="inlinecode"><span class="id" type="var">E</span></span> <span class="inlinecode"><span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span></span> <span class="inlinecode"><span class="id" type="var">K</span></span> <span class="inlinecode">⇒</span> <span class="inlinecode">..)</span>
    is like <span class="inlinecode"><span class="id" type="var">forwards</span>:</span> <span class="inlinecode"><span class="id" type="var">E</span></span> but it provides the resulting term
    to a continuation, under the name <span class="inlinecode"><span class="id" type="var">K</span></span>, and it admits
    any side-condition produced by the instantiation of <span class="inlinecode"><span class="id" type="var">E</span></span>,
    using the <span class="inlinecode"><span class="id" type="var">skip</span></span> tactic. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Inductive</span> <span class="id" type="var">ltac_goal_to_discard</span> := <span class="id" type="var">ltac_goal_to_discard_intro</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Ltac</span> <span class="id" type="var">forwards_nounfold_admit_sides_then</span> <span class="id" type="var">S</span> <span class="id" type="var">cont</span> :=<br/>
&nbsp;&nbsp;<span class="id" type="keyword">let</span> <span class="id" type="var">MARK</span> := <span class="id" type="tactic">fresh</span> "TEMP" <span class="id" type="keyword">in</span><br/>
&nbsp;&nbsp;<span class="id" type="tactic">generalize</span> <span class="id" type="var">ltac_goal_to_discard_intro</span>;<br/>
&nbsp;&nbsp;<span class="id" type="tactic">intro</span> <span class="id" type="var">MARK</span>;<br/>
&nbsp;&nbsp;<span class="id" type="var">forwards_nounfold_then</span> <span class="id" type="var">S</span> <span class="id" type="var">ltac</span>:(<span class="id" type="keyword">fun</span> <span class="id" type="var">K</span> ⇒<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">clear</span> <span class="id" type="var">MARK</span>;<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">cont</span> <span class="id" type="var">K</span>);<br/>
&nbsp;&nbsp;<span class="id" type="keyword">match</span> <span class="id" type="var">goal</span> <span class="id" type="keyword">with</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">MARK</span>: <span class="id" type="var">ltac_goal_to_discard</span> &#x22A2; <span class="id" type="var">_</span> ⇒ <span class="id" type="var">skip</span><br/>
&nbsp;&nbsp;| <span class="id" type="var">_</span> ⇒ <span class="id" type="var">idtac</span><br/>
&nbsp;&nbsp;<span class="id" type="keyword">end</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;**********************************************************************&nbsp;*)</span><br/>
</div>

<div class="doc">
<a name="lab522"></a><h1 class="section">Compatibility with standard library</h1>

<div class="paragraph"> </div>

 The module <span class="inlinecode"><span class="id" type="var">Program</span></span> contains definitions that conflict with the
    current module. If you import <span class="inlinecode"><span class="id" type="var">Program</span></span>, either directly or indirectly
    (e.g., through <span class="inlinecode"><span class="id" type="var">Setoid</span></span> or <span class="inlinecode"><span class="id" type="var">ZArith</span></span>), you will need to import the
    compability definitions through the top-level command:
    <span class="inlinecode"><span class="id" type="keyword">Import</span></span> <span class="inlinecode"><span class="id" type="var">LibTacticsCompatibility</span></span>. 
</div>
<div class="code code-tight">

<span class="id" type="keyword">Module</span> <span class="id" type="var">LibTacticsCompatibility</span>.<br/>
&nbsp;&nbsp;<span class="id" type="keyword">Tactic Notation</span> "apply" "*" <span class="id" type="var">constr</span>(<span class="id" type="var">H</span>) :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="var">sapply</span> <span class="id" type="var">H</span>; <span class="id" type="var">auto_star</span>.<br/>
&nbsp;&nbsp;<span class="id" type="keyword">Tactic Notation</span> "subst" "*" :=<br/>
&nbsp;&nbsp;&nbsp;&nbsp;<span class="id" type="tactic">subst</span>; <span class="id" type="var">auto_star</span>.<br/>
<span class="id" type="keyword">End</span> <span class="id" type="var">LibTacticsCompatibility</span>.<br/><hr class='doublespaceincode'/>
<span class="id" type="keyword">Open</span> <span class="id" type="keyword">Scope</span> <span class="id" type="var">nat_scope</span>.<br/><hr class='doublespaceincode'/>
<span class="comment">(*&nbsp;Mon&nbsp;Oct&nbsp;28&nbsp;08:15:20&nbsp;UTC&nbsp;2019&nbsp;*)</span><br/>
</div>
</div>



</div>

</body>
</html>